1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.security;
16
17 import java.io.File;
18 import java.io.FilenameFilter;
19 import java.io.IOException;
20 import java.io.PrintStream;
21 import java.security.Principal;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Properties;
29 import java.util.StringTokenizer;
30
31 import org.mortbay.component.AbstractLifeCycle;
32 import org.mortbay.jetty.Request;
33 import org.mortbay.jetty.Response;
34 import org.mortbay.jetty.UserRealm;
35 import org.mortbay.log.Log;
36 import org.mortbay.resource.Resource;
37 import org.mortbay.util.Scanner;
38 import org.mortbay.util.Scanner.BulkListener;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class HashUserRealm extends AbstractLifeCycle implements UserRealm, SSORealm
66 {
67
68
69
70 public static final String __SSO = "org.mortbay.http.SSO";
71
72
73 private String _realmName;
74 private String _config;
75 private Resource _configResource;
76 protected HashMap _users=new HashMap();
77 protected HashMap _roles=new HashMap(7);
78 private SSORealm _ssoRealm;
79 private Scanner _scanner;
80 private int _refreshInterval=0;
81
82
83
84
85
86 public HashUserRealm()
87 {}
88
89
90
91
92
93 public HashUserRealm(String name)
94 {
95 _realmName=name;
96 }
97
98
99
100
101
102
103 public HashUserRealm(String name, String config)
104 throws IOException
105 {
106 _realmName=name;
107 setConfig(config);
108 }
109
110 public String getConfig()
111 {
112 return _config;
113 }
114
115 public Resource getConfigResource()
116 {
117 return _configResource;
118 }
119
120
121
122
123
124
125
126
127
128 public void setConfig(String config)
129 throws IOException
130 {
131 _config=config;
132 _configResource=Resource.newResource(_config);
133 loadConfig();
134
135 }
136
137
138 public void setRefreshInterval (int msec)
139 {
140 _refreshInterval=msec;
141 }
142
143 public int getRefreshInterval()
144 {
145 return _refreshInterval;
146 }
147
148 protected void loadConfig ()
149 throws IOException
150 {
151 synchronized (this)
152 {
153 _users.clear();
154 _roles.clear();
155
156 if(Log.isDebugEnabled())Log.debug("Load "+this+" from "+_config);
157 Properties properties = new Properties();
158 properties.load(_configResource.getInputStream());
159
160 Iterator iter = properties.entrySet().iterator();
161 while(iter.hasNext())
162 {
163 Map.Entry entry = (Map.Entry)iter.next();
164
165 String username=entry.getKey().toString().trim();
166 String credentials=entry.getValue().toString().trim();
167 String roles=null;
168 int c=credentials.indexOf(',');
169 if (c>0)
170 {
171 roles=credentials.substring(c+1).trim();
172 credentials=credentials.substring(0,c).trim();
173 }
174
175 if (username!=null && username.length()>0 &&
176 credentials!=null && credentials.length()>0)
177 {
178 put(username,credentials);
179 if(roles!=null && roles.length()>0)
180 {
181 StringTokenizer tok = new StringTokenizer(roles,", ");
182 while (tok.hasMoreTokens())
183 addUserToRole(username,tok.nextToken());
184 }
185 }
186 }
187 }
188 }
189
190
191
192
193
194 public void setName(String name)
195 {
196 _realmName=name;
197 }
198
199
200
201
202
203 public String getName()
204 {
205 return _realmName;
206 }
207
208
209 public Principal getPrincipal(String username)
210 {
211 return (Principal)_users.get(username);
212 }
213
214
215 public Principal authenticate(String username,Object credentials,Request request)
216 {
217 KnownUser user;
218 synchronized (this)
219 {
220 user = (KnownUser)_users.get(username);
221 }
222 if (user==null)
223 return null;
224
225 if (user.authenticate(credentials))
226 return user;
227
228 return null;
229 }
230
231
232 public void disassociate(Principal user)
233 {
234 }
235
236
237 public Principal pushRole(Principal user, String role)
238 {
239 if (user==null)
240 user=new User();
241
242 return new WrappedUser(user,role);
243 }
244
245
246 public Principal popRole(Principal user)
247 {
248 WrappedUser wu = (WrappedUser)user;
249 return wu.getUserPrincipal();
250 }
251
252
253
254
255
256
257
258
259 public synchronized Object put(Object name, Object credentials)
260 {
261 if (credentials instanceof Principal)
262 return _users.put(name.toString(),credentials);
263
264 if (credentials instanceof Password)
265 return _users.put(name,new KnownUser(name.toString(),(Password)credentials));
266 if (credentials != null)
267 return _users.put(name,new KnownUser(name.toString(),Credential.getCredential(credentials.toString())));
268 return null;
269 }
270
271
272
273
274
275
276 public synchronized void addUserToRole(String userName, String roleName)
277 {
278 HashSet userSet = (HashSet)_roles.get(roleName);
279 if (userSet==null)
280 {
281 userSet=new HashSet(11);
282 _roles.put(roleName,userSet);
283 }
284 userSet.add(userName);
285 }
286
287
288 public boolean reauthenticate(Principal user)
289 {
290 return ((User)user).isAuthenticated();
291 }
292
293
294
295
296
297
298
299 public synchronized boolean isUserInRole(Principal user, String roleName)
300 {
301 if (user instanceof WrappedUser)
302 return ((WrappedUser)user).isUserInRole(roleName);
303
304 if (user==null || !(user instanceof User) || ((User)user).getUserRealm()!=this)
305 return false;
306
307 HashSet userSet = (HashSet)_roles.get(roleName);
308 return userSet!=null && userSet.contains(user.getName());
309 }
310
311
312 public void logout(Principal user)
313 {}
314
315
316 public String toString()
317 {
318 return "Realm["+_realmName+"]=="+_users.keySet();
319 }
320
321
322 public void dump(PrintStream out)
323 {
324 out.println(this+":");
325 out.println(super.toString());
326 out.println(_roles);
327 }
328
329
330
331
332
333 public SSORealm getSSORealm()
334 {
335 return _ssoRealm;
336 }
337
338
339
340
341
342
343 public void setSSORealm(SSORealm ssoRealm)
344 {
345 _ssoRealm = ssoRealm;
346 }
347
348
349 public Credential getSingleSignOn(Request request,Response response)
350 {
351 if (_ssoRealm!=null)
352 return _ssoRealm.getSingleSignOn(request,response);
353 return null;
354 }
355
356
357 public void setSingleSignOn(Request request,Response response,Principal principal,Credential credential)
358 {
359 if (_ssoRealm!=null)
360 _ssoRealm.setSingleSignOn(request,response,principal,credential);
361 }
362
363
364 public void clearSingleSignOn(String username)
365 {
366 if (_ssoRealm!=null)
367 _ssoRealm.clearSingleSignOn(username);
368 }
369
370
371
372
373
374
375
376
377 protected void doStart() throws Exception
378 {
379 super.doStart();
380 if (_scanner!=null)
381 _scanner.stop();
382
383 if (getRefreshInterval() > 0)
384 {
385 _scanner = new Scanner();
386 _scanner.setScanInterval(getRefreshInterval());
387 List dirList = new ArrayList(1);
388 dirList.add(_configResource.getFile());
389 _scanner.setScanDirs(dirList);
390 _scanner.setFilenameFilter(new FilenameFilter ()
391 {
392 public boolean accept(File dir, String name)
393 {
394 File f = new File(dir,name);
395 try
396 {
397 if (f.compareTo(_configResource.getFile())==0)
398 return true;
399 }
400 catch (IOException e)
401 {
402 return false;
403 }
404
405 return false;
406 }
407
408 });
409 _scanner.addListener(new BulkListener()
410 {
411 public void filesChanged(List filenames) throws Exception
412 {
413 if (filenames==null)
414 return;
415 if (filenames.isEmpty())
416 return;
417 if (filenames.size()==1 && filenames.get(0).equals(_config))
418 loadConfig();
419 }
420 public String toString()
421 {
422 return "HashUserRealm$Scanner";
423 }
424
425 });
426 _scanner.setReportExistingFilesOnStartup(false);
427 _scanner.setRecursive(false);
428 _scanner.start();
429 }
430 }
431
432
433
434
435 protected void doStop() throws Exception
436 {
437 super.doStop();
438 if (_scanner!=null)
439 _scanner.stop();
440 _scanner=null;
441 }
442
443
444
445
446
447
448 private class User implements Principal
449 {
450 List roles=null;
451
452
453 private UserRealm getUserRealm()
454 {
455 return HashUserRealm.this;
456 }
457
458 public String getName()
459 {
460 return "Anonymous";
461 }
462
463 public boolean isAuthenticated()
464 {
465 return false;
466 }
467
468 public String toString()
469 {
470 return getName();
471 }
472 }
473
474
475
476
477 private class KnownUser extends User
478 {
479 private String _userName;
480 private Credential _cred;
481
482
483 KnownUser(String name,Credential credential)
484 {
485 _userName=name;
486 _cred=credential;
487 }
488
489
490 boolean authenticate(Object credentials)
491 {
492 return _cred!=null && _cred.check(credentials);
493 }
494
495
496 public String getName()
497 {
498 return _userName;
499 }
500
501
502 public boolean isAuthenticated()
503 {
504 return true;
505 }
506 }
507
508
509
510
511 private class WrappedUser extends User
512 {
513 private Principal user;
514 private String role;
515
516 WrappedUser(Principal user, String role)
517 {
518 this.user=user;
519 this.role=role;
520 }
521
522 Principal getUserPrincipal()
523 {
524 return user;
525 }
526
527 public String getName()
528 {
529 return "role:"+role;
530 }
531
532 public boolean isAuthenticated()
533 {
534 return true;
535 }
536
537 public boolean isUserInRole(String role)
538 {
539 return this.role.equals(role);
540 }
541 }
542 }