1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.jaas.spi;
20
21 import java.io.IOException;
22 import java.security.Principal;
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 import javax.security.auth.Subject;
29 import javax.security.auth.callback.Callback;
30 import javax.security.auth.callback.CallbackHandler;
31 import javax.security.auth.callback.NameCallback;
32 import javax.security.auth.callback.PasswordCallback;
33 import javax.security.auth.callback.UnsupportedCallbackException;
34 import javax.security.auth.login.FailedLoginException;
35 import javax.security.auth.login.LoginException;
36 import javax.security.auth.spi.LoginModule;
37
38 import org.eclipse.jetty.jaas.JAASPrincipal;
39 import org.eclipse.jetty.jaas.JAASRole;
40 import org.eclipse.jetty.jaas.callback.ObjectCallback;
41
42
43
44
45
46
47
48 public abstract class AbstractLoginModule implements LoginModule
49 {
50 private CallbackHandler callbackHandler;
51
52 private boolean authState = false;
53 private boolean commitState = false;
54 private JAASUserInfo currentUser;
55 private Subject subject;
56
57
58
59
60
61
62
63 public class JAASUserInfo
64 {
65 private UserInfo user;
66 private Principal principal;
67 private List<JAASRole> roles;
68
69 public JAASUserInfo (UserInfo u)
70 {
71 this.user = u;
72 this.principal = new JAASPrincipal(u.getUserName());
73 }
74
75 public String getUserName ()
76 {
77 return this.user.getUserName();
78 }
79
80 public Principal getPrincipal()
81 {
82 return this.principal;
83 }
84
85
86 public void setJAASInfo (Subject subject)
87 {
88 subject.getPrincipals().add(this.principal);
89 subject.getPrivateCredentials().add(this.user.getCredential());
90 subject.getPrincipals().addAll(roles);
91 }
92
93 public void unsetJAASInfo (Subject subject)
94 {
95 subject.getPrincipals().remove(this.principal);
96 subject.getPrivateCredentials().remove(this.user.getCredential());
97 subject.getPrincipals().removeAll(this.roles);
98 }
99
100 public boolean checkCredential (Object suppliedCredential)
101 {
102 return this.user.checkCredential(suppliedCredential);
103 }
104
105 public void fetchRoles() throws Exception
106 {
107 this.user.fetchRoles();
108 this.roles = new ArrayList<JAASRole>();
109 if (this.user.getRoleNames() != null)
110 {
111 Iterator<String> itor = this.user.getRoleNames().iterator();
112 while (itor.hasNext())
113 this.roles.add(new JAASRole((String)itor.next()));
114 }
115 }
116 }
117
118 public Subject getSubject ()
119 {
120 return this.subject;
121 }
122
123 public void setSubject (Subject s)
124 {
125 this.subject = s;
126 }
127
128 public JAASUserInfo getCurrentUser()
129 {
130 return this.currentUser;
131 }
132
133 public void setCurrentUser (JAASUserInfo u)
134 {
135 this.currentUser = u;
136 }
137
138 public CallbackHandler getCallbackHandler()
139 {
140 return this.callbackHandler;
141 }
142
143 public void setCallbackHandler(CallbackHandler h)
144 {
145 this.callbackHandler = h;
146 }
147
148 public boolean isAuthenticated()
149 {
150 return this.authState;
151 }
152
153 public boolean isCommitted ()
154 {
155 return this.commitState;
156 }
157
158 public void setAuthenticated (boolean authState)
159 {
160 this.authState = authState;
161 }
162
163 public void setCommitted (boolean commitState)
164 {
165 this.commitState = commitState;
166 }
167
168
169
170
171 public boolean abort() throws LoginException
172 {
173 this.currentUser = null;
174 return (isAuthenticated() && isCommitted());
175 }
176
177
178
179
180
181
182 public boolean commit() throws LoginException
183 {
184 if (!isAuthenticated())
185 {
186 currentUser = null;
187 setCommitted(false);
188 return false;
189 }
190
191 setCommitted(true);
192 currentUser.setJAASInfo(subject);
193 return true;
194 }
195
196
197 public Callback[] configureCallbacks ()
198 {
199
200 Callback[] callbacks = new Callback[3];
201 callbacks[0] = new NameCallback("Enter user name");
202 callbacks[1] = new ObjectCallback();
203 callbacks[2] = new PasswordCallback("Enter password", false);
204 return callbacks;
205 }
206
207
208 public boolean isIgnored ()
209 {
210 return false;
211 }
212
213
214 public abstract UserInfo getUserInfo (String username) throws Exception;
215
216
217
218
219
220
221
222
223 public boolean login() throws LoginException
224 {
225 try
226 {
227 if (isIgnored())
228 return false;
229
230 if (callbackHandler == null)
231 throw new LoginException ("No callback handler");
232
233 Callback[] callbacks = configureCallbacks();
234 callbackHandler.handle(callbacks);
235
236 String webUserName = ((NameCallback)callbacks[0]).getName();
237 Object webCredential = null;
238
239 webCredential = ((ObjectCallback)callbacks[1]).getObject();
240 if (webCredential == null)
241 webCredential = ((PasswordCallback)callbacks[2]).getPassword();
242
243 if ((webUserName == null) || (webCredential == null))
244 {
245 setAuthenticated(false);
246 throw new FailedLoginException();
247 }
248
249 UserInfo userInfo = getUserInfo(webUserName);
250
251 if (userInfo == null)
252 {
253 setAuthenticated(false);
254 throw new FailedLoginException();
255 }
256
257 currentUser = new JAASUserInfo(userInfo);
258 setAuthenticated(currentUser.checkCredential(webCredential));
259
260 if (isAuthenticated())
261 {
262 currentUser.fetchRoles();
263 return true;
264 }
265 else
266 throw new FailedLoginException();
267 }
268 catch (IOException e)
269 {
270 throw new LoginException (e.toString());
271 }
272 catch (UnsupportedCallbackException e)
273 {
274 throw new LoginException (e.toString());
275 }
276 catch (Exception e)
277 {
278 if (e instanceof LoginException)
279 throw (LoginException)e;
280 throw new LoginException (e.toString());
281 }
282 }
283
284
285
286
287
288
289 public boolean logout() throws LoginException
290 {
291 this.currentUser.unsetJAASInfo(this.subject);
292 return true;
293 }
294
295
296
297
298
299
300
301
302 public void initialize(Subject subject, CallbackHandler callbackHandler,
303 Map<String,?> sharedState, Map<String,?> options)
304 {
305 this.callbackHandler = callbackHandler;
306 this.subject = subject;
307 }
308
309 }