1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.spnego;
21
22 import java.security.Principal;
23 import java.util.Set;
24
25 import javax.security.auth.Subject;
26 import javax.security.auth.callback.CallbackHandler;
27 import javax.security.auth.login.LoginContext;
28 import javax.security.auth.login.LoginException;
29
30 import org.apache.ws.security.WSSecurityException;
31 import org.ietf.jgss.GSSContext;
32 import org.ietf.jgss.GSSException;
33 import org.ietf.jgss.MessageProp;
34
35
36
37
38 public class SpnegoTokenContext {
39
40 private static final org.apache.commons.logging.Log LOG =
41 org.apache.commons.logging.LogFactory.getLog(SpnegoTokenContext.class);
42
43 private GSSContext secContext;
44 private byte[] token;
45 private boolean mutualAuth;
46 private SpnegoClientAction clientAction = new DefaultSpnegoClientAction();
47 private SpnegoServiceAction serviceAction = new DefaultSpnegoServiceAction();
48
49
50
51
52
53
54
55
56
57 public void retrieveServiceTicket(
58 String jaasLoginModuleName,
59 CallbackHandler callbackHandler,
60 String serviceName
61 ) throws WSSecurityException {
62
63 LoginContext loginContext = null;
64 try {
65 if (callbackHandler == null) {
66 loginContext = new LoginContext(jaasLoginModuleName);
67 } else {
68 loginContext = new LoginContext(jaasLoginModuleName, callbackHandler);
69 }
70 loginContext.login();
71 } catch (LoginException ex) {
72 if (LOG.isDebugEnabled()) {
73 LOG.debug(ex.getMessage(), ex);
74 }
75 throw new WSSecurityException(
76 WSSecurityException.FAILURE,
77 "kerberosLoginError",
78 new Object[] {ex.getMessage()},
79 ex
80 );
81 }
82 if (LOG.isDebugEnabled()) {
83 LOG.debug("Successfully authenticated to the TGT");
84 }
85
86 Subject clientSubject = loginContext.getSubject();
87 Set<Principal> clientPrincipals = clientSubject.getPrincipals();
88 if (clientPrincipals.isEmpty()) {
89 throw new WSSecurityException(
90 WSSecurityException.FAILURE,
91 "kerberosLoginError",
92 new Object[] {"No Client principals found after login"}
93 );
94 }
95
96
97 clientAction.setServiceName(serviceName);
98 clientAction.setMutualAuth(mutualAuth);
99 token = (byte[])Subject.doAs(clientSubject, clientAction);
100 if (token == null) {
101 throw new WSSecurityException(
102 WSSecurityException.FAILURE, "kerberosServiceTicketError"
103 );
104 }
105
106 secContext = clientAction.getContext();
107 if (LOG.isDebugEnabled()) {
108 LOG.debug("Successfully retrieved a service ticket");
109 }
110
111 }
112
113
114
115
116
117
118
119
120
121 public void validateServiceTicket(
122 String jaasLoginModuleName,
123 CallbackHandler callbackHandler,
124 String serviceName,
125 byte[] ticket
126 ) throws WSSecurityException {
127
128 LoginContext loginContext = null;
129 try {
130 if (callbackHandler == null) {
131 loginContext = new LoginContext(jaasLoginModuleName);
132 } else {
133 loginContext = new LoginContext(jaasLoginModuleName, callbackHandler);
134 }
135 loginContext.login();
136 } catch (LoginException ex) {
137 if (LOG.isDebugEnabled()) {
138 LOG.debug(ex.getMessage(), ex);
139 }
140 throw new WSSecurityException(
141 WSSecurityException.FAILURE,
142 "kerberosLoginError",
143 new Object[] {ex.getMessage()},
144 ex
145 );
146 }
147 if (LOG.isDebugEnabled()) {
148 LOG.debug("Successfully authenticated to the TGT");
149 }
150
151
152 Subject subject = loginContext.getSubject();
153 String service = serviceName;
154 if (service == null) {
155 Set<Principal> principals = subject.getPrincipals();
156 if (principals.isEmpty()) {
157 throw new WSSecurityException(
158 WSSecurityException.FAILURE,
159 "kerberosLoginError",
160 new Object[] {"No Client principals found after login"}
161 );
162 }
163 service = principals.iterator().next().getName();
164 }
165
166
167 serviceAction.setTicket(ticket);
168 serviceAction.setServiceName(service);
169 token = (byte[])Subject.doAs(subject, serviceAction);
170
171 secContext = serviceAction.getContext();
172 if (LOG.isDebugEnabled()) {
173 LOG.debug("Successfully validated a service ticket");
174 }
175
176 }
177
178
179
180
181 public void setMutualAuth(boolean mutualAuthentication) {
182 mutualAuth = mutualAuthentication;
183 }
184
185
186
187
188 public byte[] getToken() {
189 return token;
190 }
191
192
193
194
195 public boolean isEstablished() {
196 if (secContext == null) {
197 return false;
198 }
199 return secContext.isEstablished();
200 }
201
202
203
204
205 public byte[] unwrapKey(byte[] secret) throws WSSecurityException {
206 MessageProp mProp = new MessageProp(0, true);
207 try {
208 return secContext.unwrap(secret, 0, secret.length, mProp);
209 } catch (GSSException e) {
210 if (LOG.isDebugEnabled()) {
211 LOG.debug("Error in cleaning up a GSS context", e);
212 }
213 throw new WSSecurityException(
214 WSSecurityException.FAILURE, "spnegoKeyError", null, e
215 );
216 }
217 }
218
219
220
221
222 public byte[] wrapKey(byte[] secret) throws WSSecurityException {
223 MessageProp mProp = new MessageProp(0, true);
224 try {
225 return secContext.wrap(secret, 0, secret.length, mProp);
226 } catch (GSSException e) {
227 if (LOG.isDebugEnabled()) {
228 LOG.debug("Error in cleaning up a GSS context", e);
229 }
230 throw new WSSecurityException(
231 WSSecurityException.FAILURE, "spnegoKeyError", null, e
232 );
233 }
234 }
235
236
237
238
239 public void setSpnegoClientAction(SpnegoClientAction spnegoClientAction) {
240 this.clientAction = spnegoClientAction;
241 }
242
243
244
245
246 public void setSpnegoServiceAction(SpnegoServiceAction spnegoServiceAction) {
247 this.serviceAction = spnegoServiceAction;
248 }
249
250 public void clear() {
251 token = null;
252 mutualAuth = false;
253 try {
254 secContext.dispose();
255 } catch (GSSException e) {
256 if (LOG.isDebugEnabled()) {
257 LOG.debug("Error in cleaning up a GSS context", e);
258 }
259 }
260 }
261
262 }