1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.plus.jaas;
15
16 import java.io.IOException;
17 import java.security.Principal;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.LinkedHashSet;
22 import java.util.Set;
23
24 import javax.security.auth.Subject;
25 import javax.security.auth.callback.Callback;
26 import javax.security.auth.callback.CallbackHandler;
27 import javax.security.auth.callback.NameCallback;
28 import javax.security.auth.callback.PasswordCallback;
29 import javax.security.auth.callback.UnsupportedCallbackException;
30 import javax.security.auth.login.LoginContext;
31 import javax.security.auth.login.LoginException;
32
33 import org.eclipse.jetty.plus.jaas.callback.ObjectCallback;
34 import org.eclipse.jetty.security.DefaultIdentityService;
35 import org.eclipse.jetty.security.IdentityService;
36 import org.eclipse.jetty.security.LoginService;
37 import org.eclipse.jetty.server.UserIdentity;
38 import org.eclipse.jetty.util.component.AbstractLifeCycle;
39 import org.eclipse.jetty.util.log.Log;
40
41
42
43
44
45
46 public class JAASLoginService extends AbstractLifeCycle implements LoginService
47 {
48 public static String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.plus.jaas.JAASRole";
49 public static String[] DEFAULT_ROLE_CLASS_NAMES = {DEFAULT_ROLE_CLASS_NAME};
50
51 protected String[] _roleClassNames = DEFAULT_ROLE_CLASS_NAMES;
52 protected String _callbackHandlerClass;
53 protected String _realmName;
54 protected String _loginModuleName;
55 protected JAASUserPrincipal _defaultUser = new JAASUserPrincipal(null, null, null);
56 protected IdentityService _identityService;
57
58
59
60
61
62
63 public JAASLoginService()
64 {
65 }
66
67
68
69
70
71
72
73
74 public JAASLoginService(String name)
75 {
76 this();
77 _realmName = name;
78 _loginModuleName = name;
79 }
80
81
82
83
84
85
86
87
88 public String getName()
89 {
90 return _realmName;
91 }
92
93
94
95
96
97
98
99
100 public void setName (String name)
101 {
102 _realmName = name;
103 }
104
105
106
107
108
109 public IdentityService getIdentityService()
110 {
111 return _identityService;
112 }
113
114
115
116
117
118 public void setIdentityService(IdentityService identityService)
119 {
120 _identityService = identityService;
121 }
122
123
124
125
126
127
128
129
130 public void setLoginModuleName (String name)
131 {
132 _loginModuleName = name;
133 }
134
135
136 public void setCallbackHandlerClass (String classname)
137 {
138 _callbackHandlerClass = classname;
139 }
140
141
142 public void setRoleClassNames (String[] classnames)
143 {
144 ArrayList<String> tmp = new ArrayList<String>();
145
146 if (classnames != null)
147 tmp.addAll(Arrays.asList(classnames));
148
149 if (!tmp.contains(DEFAULT_ROLE_CLASS_NAME))
150 tmp.add(DEFAULT_ROLE_CLASS_NAME);
151 _roleClassNames = tmp.toArray(new String[tmp.size()]);
152 }
153
154
155 public String[] getRoleClassNames()
156 {
157 return _roleClassNames;
158 }
159
160
161
162
163
164 protected void doStart() throws Exception
165 {
166 if (_identityService==null)
167 _identityService=new DefaultIdentityService();
168 super.doStart();
169 }
170
171
172 public UserIdentity login(final String username,final Object credentials)
173 {
174 try
175 {
176 CallbackHandler callbackHandler = new CallbackHandler()
177 {
178
179 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
180 {
181 for (Callback callback: callbacks)
182 {
183 if (callback instanceof NameCallback)
184 {
185 ((NameCallback)callback).setName(username);
186 }
187 else if (callback instanceof PasswordCallback)
188 {
189 ((PasswordCallback)callback).setPassword((char[]) credentials.toString().toCharArray());
190 }
191 else if (callback instanceof ObjectCallback)
192 {
193 ((ObjectCallback)callback).setObject(credentials);
194 }
195 }
196 }
197 };
198
199
200 Subject subject = new Subject();
201 LoginContext loginContext = new LoginContext(_loginModuleName, subject, callbackHandler);
202
203 loginContext.login();
204
205
206 JAASUserPrincipal userPrincipal = new JAASUserPrincipal(getUserName(callbackHandler), subject, loginContext);
207 subject.getPrincipals().add(userPrincipal);
208
209 return _identityService.newUserIdentity(subject,userPrincipal,getGroups(subject));
210 }
211 catch (LoginException e)
212 {
213 Log.warn(e);
214 }
215 catch (IOException e)
216 {
217 Log.warn(e);
218 }
219 catch (UnsupportedCallbackException e)
220 {
221 Log.warn(e);
222 }
223 return null;
224 }
225
226
227 public boolean validate(UserIdentity user)
228 {
229
230 return true;
231 }
232
233
234 private String getUserName(CallbackHandler callbackHandler) throws IOException, UnsupportedCallbackException
235 {
236 NameCallback nameCallback = new NameCallback("foo");
237 callbackHandler.handle(new Callback[] {nameCallback});
238 return nameCallback.getName();
239 }
240
241
242 public void logout(UserIdentity user)
243 {
244 Set<JAASUserPrincipal> userPrincipals = user.getSubject().getPrincipals(JAASUserPrincipal.class);
245 LoginContext loginContext = userPrincipals.iterator().next().getLoginContext();
246 try
247 {
248 loginContext.logout();
249 }
250 catch (LoginException e)
251 {
252 Log.warn(e);
253 }
254 }
255
256
257
258 private String[] getGroups (Subject subject)
259 {
260
261 String[] roleClassNames = getRoleClassNames();
262 Collection<String> groups = new LinkedHashSet<String>();
263 try
264 {
265 for (String roleClassName : roleClassNames)
266 {
267 Class load_class = Thread.currentThread().getContextClassLoader().loadClass(roleClassName);
268 Set<Principal> rolesForType = subject.getPrincipals(load_class);
269 for (Principal principal : rolesForType)
270 {
271 groups.add(principal.getName());
272 }
273 }
274
275 return groups.toArray(new String[groups.size()]);
276 }
277 catch (ClassNotFoundException e)
278 {
279 throw new RuntimeException(e);
280 }
281 }
282
283 }