KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > http > HashUserRealm


1 // ========================================================================
2
// $Id: HashUserRealm.java,v 1.29 2005/08/13 00:01:24 gregwilkins Exp $
3
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.http;
17
18 import java.io.Externalizable JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.PrintStream JavaDoc;
21 import java.security.Principal JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Properties JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 import org.apache.commons.logging.Log;
31 import org.mortbay.log.LogFactory;
32 import org.mortbay.util.Credential;
33 import org.mortbay.util.Password;
34 import org.mortbay.util.Resource;
35
36 /* ------------------------------------------------------------ */
37 /** HashMapped User Realm.
38  *
39  * An implementation of UserRealm that stores users and roles in-memory in
40  * HashMaps.
41  * <P>
42  * Typically these maps are populated by calling the load() method or passing
43  * a properties resource to the constructor. The format of the properties
44  * file is: <PRE>
45  * username: password [,rolename ...]
46  * </PRE>
47  * Passwords may be clear text, obfuscated or checksummed. The class
48  * com.mortbay.Util.Password should be used to generate obfuscated
49  * passwords or password checksums.
50  *
51  * If DIGEST Authentication is used, the password must be in a recoverable
52  * format, either plain text or OBF:.
53  *
54  * The HashUserRealm also implements SSORealm but provides no implementation
55  * of SSORealm. Instead setSSORealm may be used to provide a delegate
56  * SSORealm implementation.
57  *
58  * @see Password
59  * @version $Id: HashUserRealm.java,v 1.29 2005/08/13 00:01:24 gregwilkins Exp $
60  * @author Greg Wilkins (gregw)
61  */

62 public class HashUserRealm
63     extends HashMap JavaDoc
64     implements UserRealm, SSORealm, Externalizable JavaDoc
65 {
66     private static Log log = LogFactory.getLog(HashUserRealm.class);
67
68     /** HttpContext Attribute to set to activate SSO.
69      */

70     public static final String JavaDoc __SSO = "org.mortbay.http.SSO";
71     
72     /* ------------------------------------------------------------ */
73     private String JavaDoc _realmName;
74     private String JavaDoc _config;
75     protected HashMap JavaDoc _roles=new HashMap JavaDoc(7);
76     private SSORealm _ssoRealm;
77     
78
79     /* ------------------------------------------------------------ */
80     /** Constructor.
81      */

82     public HashUserRealm()
83     {}
84     
85     /* ------------------------------------------------------------ */
86     /** Constructor.
87      * @param name Realm Name
88      */

89     public HashUserRealm(String JavaDoc name)
90     {
91         _realmName=name;
92     }
93     
94     /* ------------------------------------------------------------ */
95     /** Constructor.
96      * @param name Realm name
97      * @param config Filename or url of user properties file.
98      */

99     public HashUserRealm(String JavaDoc name, String JavaDoc config)
100         throws IOException JavaDoc
101     {
102         _realmName=name;
103         load(config);
104     }
105     
106     /* ------------------------------------------------------------ */
107     public void writeExternal(java.io.ObjectOutput JavaDoc out)
108         throws java.io.IOException JavaDoc
109     {
110         out.writeObject(_realmName);
111         out.writeObject(_config);
112     }
113     
114     /* ------------------------------------------------------------ */
115     public void readExternal(java.io.ObjectInput JavaDoc in)
116         throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
117     {
118         _realmName= (String JavaDoc)in.readObject();
119         _config=(String JavaDoc)in.readObject();
120         if (_config!=null)
121             load(_config);
122     }
123     
124
125     /* ------------------------------------------------------------ */
126     /** Load realm users from properties file.
127      * The property file maps usernames to password specs followed by
128      * an optional comma separated list of role names.
129      *
130      * @param config Filename or url of user properties file.
131      * @exception IOException
132      */

133     public void load(String JavaDoc config)
134         throws IOException JavaDoc
135     {
136         _config=config;
137         if(log.isDebugEnabled())log.debug("Load "+this+" from "+config);
138         Properties JavaDoc properties = new Properties JavaDoc();
139         Resource resource=Resource.newResource(config);
140         properties.load(resource.getInputStream());
141
142         Iterator JavaDoc iter = properties.entrySet().iterator();
143         while(iter.hasNext())
144         {
145             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)iter.next();
146
147             String JavaDoc username=entry.getKey().toString().trim();
148             String JavaDoc credentials=entry.getValue().toString().trim();
149             String JavaDoc roles=null;
150             int c=credentials.indexOf(',');
151             if (c>0)
152             {
153                 roles=credentials.substring(c+1).trim();
154                 credentials=credentials.substring(0,c).trim();
155             }
156
157             if (username!=null && username.length()>0 &&
158                 credentials!=null && credentials.length()>0)
159             {
160                 put(username,credentials);
161                 if(roles!=null && roles.length()>0)
162                 {
163                     StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(roles,", ");
164                     while (tok.hasMoreTokens())
165                         addUserToRole(username,tok.nextToken());
166                 }
167             }
168         }
169     }
170     
171     /* ------------------------------------------------------------ */
172     /**
173      * @param name The realm name
174      */

175     public void setName(String JavaDoc name)
176     {
177         _realmName=name;
178     }
179     
180     /* ------------------------------------------------------------ */
181     /**
182      * @return The realm name.
183      */

184     public String JavaDoc getName()
185     {
186         return _realmName;
187     }
188
189     /* ------------------------------------------------------------ */
190     public Principal JavaDoc getPrincipal(String JavaDoc username)
191     {
192         return (Principal JavaDoc)super.get(username);
193     }
194     
195     /* ------------------------------------------------------------ */
196     public Principal JavaDoc authenticate(String JavaDoc username,
197                                   Object JavaDoc credentials,
198                                   HttpRequest request)
199     {
200         KnownUser user;
201         synchronized (this)
202         {
203             user = (KnownUser)super.get(username);
204         }
205         if (user==null)
206             return null;
207
208         if (user.authenticate(credentials))
209             return user;
210         
211         return null;
212     }
213     
214     /* ------------------------------------------------------------ */
215     public void disassociate(Principal JavaDoc user)
216     {
217     }
218     
219     /* ------------------------------------------------------------ */
220     public Principal JavaDoc pushRole(Principal JavaDoc user, String JavaDoc role)
221     {
222         if (user==null)
223             user=new User();
224         
225         return new WrappedUser(user,role);
226     }
227
228     /* ------------------------------------------------------------ */
229     public Principal JavaDoc popRole(Principal JavaDoc user)
230     {
231         WrappedUser wu = (WrappedUser)user;
232         return wu.getUserPrincipal();
233     }
234     
235     /* ------------------------------------------------------------ */
236     /** Put user into realm.
237      * @param name User name
238      * @param credentials String password, Password or UserPrinciple
239      * instance.
240      * @return Old UserPrinciple value or null
241      */

242     public synchronized Object JavaDoc put(Object JavaDoc name, Object JavaDoc credentials)
243     {
244         if (credentials instanceof Principal JavaDoc)
245             return super.put(name.toString(),
246                              credentials);
247         
248         if (credentials instanceof Password)
249             return super.put(name,
250                              new KnownUser(name.toString(),
251                                           (Password)credentials));
252         if (credentials != null)
253             return super
254                 .put(name,
255                      new KnownUser(name.toString(),
256                                    Credential.getCredential(credentials.toString())));
257         return null;
258     }
259
260     /* ------------------------------------------------------------ */
261     /** Add a user to a role.
262      * @param userName
263      * @param roleName
264      */

265     public synchronized void addUserToRole(String JavaDoc userName, String JavaDoc roleName)
266     {
267         HashSet JavaDoc userSet = (HashSet JavaDoc)_roles.get(roleName);
268         if (userSet==null)
269         {
270             userSet=new HashSet JavaDoc(11);
271             _roles.put(roleName,userSet);
272         }
273         userSet.add(userName);
274     }
275     
276     /* -------------------------------------------------------- */
277     public boolean reauthenticate(Principal JavaDoc user)
278     {
279         return ((User)user).isAuthenticated();
280     }
281     
282     /* ------------------------------------------------------------ */
283     /** Check if a user is in a role.
284      * @param user The user, which must be from this realm
285      * @param roleName
286      * @return True if the user can act in the role.
287      */

288     public synchronized boolean isUserInRole(Principal JavaDoc user, String JavaDoc roleName)
289     {
290         if (user instanceof WrappedUser)
291             return ((WrappedUser)user).isUserInRole(roleName);
292          
293         if (user==null || ((User)user).getUserRealm()!=this)
294             return false;
295         
296         HashSet JavaDoc userSet = (HashSet JavaDoc)_roles.get(roleName);
297         return userSet!=null && userSet.contains(user.getName());
298     }
299
300     /* ------------------------------------------------------------ */
301     public void logout(Principal JavaDoc user)
302     {}
303     
304     /* ------------------------------------------------------------ */
305     public String JavaDoc toString()
306     {
307         return "Realm["+_realmName+"]";
308     }
309     
310     /* ------------------------------------------------------------ */
311     public void dump(PrintStream JavaDoc out)
312     {
313         out.println(this+":");
314         out.println(super.toString());
315         out.println(_roles);
316     }
317     
318     /* ------------------------------------------------------------ */
319     /**
320      * @return The SSORealm to delegate single sign on requests to.
321      */

322     public SSORealm getSSORealm()
323     {
324         return _ssoRealm;
325     }
326     
327     /* ------------------------------------------------------------ */
328     /** Set the SSORealm.
329      * A SSORealm implementation may be set to enable support for SSO.
330      * @param ssoRealm The SSORealm to delegate single sign on requests to.
331      */

332     public void setSSORealm(SSORealm ssoRealm)
333     {
334         _ssoRealm = ssoRealm;
335     }
336     
337     /* ------------------------------------------------------------ */
338     public Credential getSingleSignOn(HttpRequest request,
339                                       HttpResponse response)
340     {
341         if (_ssoRealm!=null)
342             return _ssoRealm.getSingleSignOn(request,response);
343         return null;
344     }
345     
346     
347     /* ------------------------------------------------------------ */
348     public void setSingleSignOn(HttpRequest request,
349                                 HttpResponse response,
350                                 Principal JavaDoc principal,
351                                 Credential credential)
352     {
353         if (_ssoRealm!=null)
354             _ssoRealm.setSingleSignOn(request,response,principal,credential);
355     }
356     
357     /* ------------------------------------------------------------ */
358     public void clearSingleSignOn(String JavaDoc username)
359     {
360         if (_ssoRealm!=null)
361             _ssoRealm.clearSingleSignOn(username);
362     }
363     
364     /* ------------------------------------------------------------ */
365     /* ------------------------------------------------------------ */
366     /* ------------------------------------------------------------ */
367     private class User implements Principal JavaDoc
368     {
369         List JavaDoc roles=null;
370
371         /* ------------------------------------------------------------ */
372         private UserRealm getUserRealm()
373         {
374             return HashUserRealm.this;
375         }
376         
377         public String JavaDoc getName()
378         {
379             return "Anonymous";
380         }
381                 
382         public boolean isAuthenticated()
383         {
384             return false;
385         }
386         
387         public String JavaDoc toString()
388         {
389             return getName();
390         }
391     }
392     
393     /* ------------------------------------------------------------ */
394     /* ------------------------------------------------------------ */
395     /* ------------------------------------------------------------ */
396     private class KnownUser extends User
397     {
398         private String JavaDoc _userName;
399         private Credential _cred;
400         
401         /* -------------------------------------------------------- */
402         KnownUser(String JavaDoc name,Credential credential)
403         {
404             _userName=name;
405             _cred=credential;
406         }
407         
408         /* -------------------------------------------------------- */
409         boolean authenticate(Object JavaDoc credentials)
410         {
411             return _cred!=null && _cred.check(credentials);
412         }
413         
414         /* ------------------------------------------------------------ */
415         public String JavaDoc getName()
416         {
417             return _userName;
418         }
419         
420         /* -------------------------------------------------------- */
421         public boolean isAuthenticated()
422         {
423             return true;
424         }
425     }
426
427     /* ------------------------------------------------------------ */
428     /* ------------------------------------------------------------ */
429     /* ------------------------------------------------------------ */
430     private class WrappedUser extends User
431     {
432         private Principal JavaDoc user;
433         private String JavaDoc role;
434
435         WrappedUser(Principal JavaDoc user, String JavaDoc role)
436         {
437             this.user=user;
438             this.role=role;
439         }
440
441         Principal JavaDoc getUserPrincipal()
442         {
443             return user;
444         }
445
446         public String JavaDoc getName()
447         {
448             return "role:"+role;
449         }
450                 
451         public boolean isAuthenticated()
452         {
453             return true;
454         }
455         
456         public boolean isUserInRole(String JavaDoc role)
457         {
458             return this.role.equals(role);
459         }
460     }
461 }
462
Popular Tags