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