KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > realm > UserDatabaseRealm


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.realm;
20
21
22 import java.security.Principal JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26
27 import javax.naming.Context JavaDoc;
28
29 import org.apache.catalina.Group;
30 import org.apache.catalina.LifecycleException;
31 import org.apache.catalina.Role;
32 import org.apache.catalina.ServerFactory;
33 import org.apache.catalina.User;
34 import org.apache.catalina.UserDatabase;
35 import org.apache.catalina.core.StandardServer;
36 import org.apache.catalina.users.MemoryUser;
37 import org.apache.catalina.util.StringManager;
38
39
40 /**
41  * <p>Implementation of {@link org.apache.catalina.Realm} that is based on an implementation of
42  * {@link UserDatabase} made available through the global JNDI resources
43  * configured for this instance of Catalina. Set the <code>resourceName</code>
44  * parameter to the global JNDI resources name for the configured instance
45  * of <code>UserDatabase</code> that we should consult.</p>
46  *
47  * @author Craig R. McClanahan
48  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
49  * @since 4.1
50  */

51
52 public class UserDatabaseRealm
53     extends RealmBase {
54
55
56     // ----------------------------------------------------- Instance Variables
57

58
59     /**
60      * The <code>UserDatabase</code> we will use to authenticate users
61      * and identify associated roles.
62      */

63     protected UserDatabase database = null;
64
65
66     /**
67      * Descriptive information about this Realm implementation.
68      */

69     protected final String JavaDoc info =
70         "org.apache.catalina.realm.UserDatabaseRealm/1.0";
71
72
73     /**
74      * Descriptive information about this Realm implementation.
75      */

76     protected static final String JavaDoc name = "UserDatabaseRealm";
77
78
79     /**
80      * The global JNDI name of the <code>UserDatabase</code> resource
81      * we will be utilizing.
82      */

83     protected String JavaDoc resourceName = "UserDatabase";
84
85
86     /**
87      * The string manager for this package.
88      */

89     private static StringManager sm =
90         StringManager.getManager(Constants.Package);
91
92
93     // ------------------------------------------------------------- Properties
94

95
96     /**
97      * Return descriptive information about this Realm implementation and
98      * the corresponding version number, in the format
99      * <code>&lt;description&gt;/&lt;version&gt;</code>.
100      */

101     public String JavaDoc getInfo() {
102
103         return info;
104
105     }
106
107
108     /**
109      * Return the global JNDI name of the <code>UserDatabase</code> resource
110      * we will be using.
111      */

112     public String JavaDoc getResourceName() {
113
114         return resourceName;
115
116     }
117
118
119     /**
120      * Set the global JNDI name of the <code>UserDatabase</code> resource
121      * we will be using.
122      *
123      * @param resourceName The new global JNDI name
124      */

125     public void setResourceName(String JavaDoc resourceName) {
126
127         this.resourceName = resourceName;
128
129     }
130
131
132     // --------------------------------------------------------- Public Methods
133

134
135     /**
136      * Return <code>true</code> if the specified Principal has the specified
137      * security role, within the context of this Realm; otherwise return
138      * <code>false</code>. This implementation returns <code>true</code>
139      * if the <code>User</code> has the role, or if any <code>Group</code>
140      * that the <code>User</code> is a member of has the role.
141      *
142      * @param principal Principal for whom the role is to be checked
143      * @param role Security role to be checked
144      */

145     public boolean hasRole(Principal JavaDoc principal, String JavaDoc role) {
146         if( principal instanceof GenericPrincipal) {
147             GenericPrincipal gp = (GenericPrincipal)principal;
148             if(gp.getUserPrincipal() instanceof User) {
149                 principal = gp.getUserPrincipal();
150             }
151         }
152         if(! (principal instanceof User) ) {
153             //Play nice with SSO and mixed Realms
154
return super.hasRole(principal, role);
155         }
156         if("*".equals(role)) {
157             return true;
158         } else if(role == null) {
159             return false;
160         }
161         User user = (User)principal;
162         Role dbrole = database.findRole(role);
163         if(dbrole == null) {
164             return false;
165         }
166         if(user.isInRole(dbrole)) {
167             return true;
168         }
169         Iterator JavaDoc groups = user.getGroups();
170         while(groups.hasNext()) {
171             Group group = (Group)groups.next();
172             if(group.isInRole(dbrole)) {
173                 return true;
174             }
175         }
176         return false;
177     }
178         
179     // ------------------------------------------------------ Protected Methods
180

181
182     /**
183      * Return a short name for this Realm implementation.
184      */

185     protected String JavaDoc getName() {
186
187         return (name);
188
189     }
190
191
192     /**
193      * Return the password associated with the given principal's user name.
194      */

195     protected String JavaDoc getPassword(String JavaDoc username) {
196
197         User user = database.findUser(username);
198
199         if (user == null) {
200             return null;
201         }
202
203         return (user.getPassword());
204
205     }
206
207
208     /**
209      * Return the Principal associated with the given user name.
210      */

211     protected Principal JavaDoc getPrincipal(String JavaDoc username) {
212
213         User user = database.findUser(username);
214         if(user == null) {
215             return null;
216         }
217
218         List JavaDoc roles = new ArrayList JavaDoc();
219         Iterator JavaDoc uroles = user.getRoles();
220         while(uroles.hasNext()) {
221             Role role = (Role)uroles.next();
222             roles.add(role.getName());
223         }
224         Iterator JavaDoc groups = user.getGroups();
225         while(groups.hasNext()) {
226             Group group = (Group)groups.next();
227             uroles = group.getRoles();
228             while(uroles.hasNext()) {
229                 Role role = (Role)uroles.next();
230                 roles.add(role.getName());
231             }
232         }
233         return new GenericPrincipal(this, username, user.getPassword(), roles, user);
234     }
235
236
237     // ------------------------------------------------------ Lifecycle Methods
238

239
240     /**
241      * Prepare for active use of the public methods of this Component.
242      *
243      * @exception LifecycleException if this component detects a fatal error
244      * that prevents it from being started
245      */

246     public synchronized void start() throws LifecycleException {
247
248         // Perform normal superclass initialization
249
super.start();
250
251         try {
252             StandardServer server = (StandardServer) ServerFactory.getServer();
253             Context JavaDoc context = server.getGlobalNamingContext();
254             database = (UserDatabase) context.lookup(resourceName);
255         } catch (Throwable JavaDoc e) {
256             containerLog.error(sm.getString("userDatabaseRealm.lookup",
257                                             resourceName),
258                                e);
259             database = null;
260         }
261         if (database == null) {
262             throw new LifecycleException
263                 (sm.getString("userDatabaseRealm.noDatabase", resourceName));
264         }
265
266     }
267
268
269     /**
270      * Gracefully shut down active use of the public methods of this Component.
271      *
272      * @exception LifecycleException if this component detects a fatal error
273      * that needs to be reported
274      */

275     public synchronized void stop() throws LifecycleException {
276
277         // Perform normal superclass finalization
278
super.stop();
279
280         // Release reference to our user database
281
database = null;
282
283     }
284
285
286 }
287
Popular Tags