001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * Initial developer(s): Greg Wilkins for the HashUserRealm
022: * Copyright (c) 1996 Mort Bay Consulting Pty. Ltd. All rights reserved.
023: * --------------------------------------------------------------------------
024: * $Id: Standard.java 6661 2005-04-28 08:43:27Z benoitf $
025: * --------------------------------------------------------------------------
026: */package org.objectweb.jonas.security.realm.web.jetty50;
027:
028: import java.security.Principal;
029: import java.util.ArrayList;
030: import java.util.HashMap;
031: import java.util.Map;
032:
033: import org.mortbay.http.HttpRequest;
034: import org.mortbay.http.UserRealm;
035:
036: import org.objectweb.jonas.common.Log;
037: import org.objectweb.jonas.security.SecurityService;
038: import org.objectweb.jonas.security.realm.factory.JResource;
039: import org.objectweb.jonas.security.realm.principals.User;
040: import org.objectweb.jonas.service.ServiceManager;
041:
042: import org.objectweb.security.context.SecurityContext;
043: import org.objectweb.security.context.SecurityCurrent;
044:
045: import org.objectweb.util.monolog.api.BasicLevel;
046: import org.objectweb.util.monolog.api.Logger;
047:
048: /**
049: * <p>
050: * Implementation of a Realm. Use any JOnAS realm by specifying the resource
051: * name
052: * @author Greg Wilkins for the HashUserRealm
053: * @author Florent Benoit : Jetty 4.2.x / JOnAS 3.1
054: */
055: public class Standard implements UserRealm {
056:
057: /**
058: * The logger used in JOnAS
059: */
060: private static Logger logger = null;
061:
062: /**
063: * Name of this realm
064: */
065: private String name;
066:
067: /**
068: * The resource we will use to authenticate users and identify associated
069: * roles.
070: */
071: private JResource jResource = null;
072:
073: /**
074: * Reference to the JOnAS security service
075: */
076: private SecurityService securityService = null;
077:
078: /**
079: * List of authenticated users
080: */
081: private Map users = null;
082:
083: /**
084: * Default Constructor
085: */
086: protected Standard() {
087: users = new HashMap();
088:
089: if (logger == null) {
090: logger = Log.getLogger(Log.JONAS_SECURITY_PREFIX);
091: }
092: }
093:
094: /**
095: * Constructor
096: * @param resourceName name of the resource to use
097: * @throws Exception if the resource can't be retrieved
098: */
099: public Standard(String resourceName) throws Exception {
100: this ();
101:
102: // Get the Security Service
103: try {
104: securityService = (SecurityService) ServiceManager
105: .getInstance().getSecurityService();
106: } catch (Exception e) {
107: // Can't retrieve Security service
108: throw new Exception("can't retrieve Security service", e);
109: }
110:
111: // Get the resource from the security service
112: jResource = securityService.getJResource(resourceName);
113: if (jResource == null) {
114: throw new Exception("Can't retrieve resource "
115: + resourceName + "from the security service");
116: }
117: }
118:
119: /**
120: * Constructor
121: * @param name name of the realm
122: * @param resourceName name of the resource to use
123: * @throws Exception if the resource can't be retrieved
124: */
125: public Standard(String name, String resourceName) throws Exception {
126: this (resourceName);
127: this .name = name;
128: }
129:
130: /**
131: * @return The realm name.
132: */
133: public String getName() {
134: return name;
135: }
136:
137: /**
138: * Authenticate a user with a specific username and credentials
139: * @param username name of the user
140: * @param credentials credential of the user
141: * @param request httprequest
142: * @return a Jetty principal
143: */
144: public Principal authenticate(String username, Object credentials,
145: HttpRequest request) {
146:
147: // No authentication can be made with a null username
148: if (username == null) {
149: return null;
150: }
151:
152: Principal jettyPrincipal = (Principal) users.get(username);
153: // User previously authenticated --> remove from the cache
154: if (jettyPrincipal != null) {
155: users.remove(username);
156: }
157:
158: // Does a user with this username exist?
159: User user = null;
160: try {
161: user = jResource.findUser(username);
162: } catch (Exception jre) {
163: // could not retrieve user
164: logger.log(BasicLevel.INFO, jre.getMessage());
165: return null;
166: }
167:
168: // User was not found
169: if (user == null) {
170: if (logger.isLoggable(BasicLevel.DEBUG)) {
171: logger.log(BasicLevel.DEBUG, "User " + username
172: + " not found.");
173: }
174: return null;
175: }
176:
177: if (!(credentials instanceof String)) {
178: logger.log(BasicLevel.ERROR,
179: "Allow only string type as credentials");
180: return null;
181: }
182:
183: boolean validated = jResource.isValidUser(user,
184: (String) credentials);
185:
186: if (!validated) {
187: logger.log(BasicLevel.INFO, "The password for the user "
188: + username + " is not valid");
189: return null;
190: }
191:
192: ArrayList combinedRoles = null;
193: try {
194: combinedRoles = jResource.getArrayListCombinedRoles(user);
195: } catch (Exception jre) {
196: logger.log(BasicLevel.ERROR, jre.getMessage());
197: return null;
198: }
199:
200: Principal principal = new JettyPrincipal(user.getName(),
201: combinedRoles);
202: SecurityContext ctx = new SecurityContext(principal.getName(),
203: combinedRoles);
204: SecurityCurrent current = SecurityCurrent.getCurrent();
205: current.setSecurityContext(ctx);
206:
207: // Add to cache
208: users.put(username, principal);
209:
210: return principal;
211: }
212:
213: /**
214: * Check if a user is in a role.
215: * @param user The user, which must be from this realm
216: * @param roleName the role to test for the given user
217: * @return True if the user can act in the role.
218: */
219: public synchronized boolean isUserInRole(Principal user,
220: String roleName) {
221: if (user == null) {
222: return false;
223: }
224:
225: if (user instanceof JettyPrincipal) {
226: return ((JettyPrincipal) user).isUserInRole(roleName);
227: } else {
228: logger.log(BasicLevel.ERROR, "The user '" + user
229: + "' is not instance of JettyPrincipal");
230: return false;
231: }
232: }
233:
234: /**
235: * Check if a user is authenticated
236: * @param user The user, which must be from this realm
237: * @return True if the user is authenticated
238: */
239: public boolean isAuthenticated(Principal user) {
240: if (user == null) {
241: return false;
242: }
243:
244: if (user instanceof JettyPrincipal) {
245: return ((JettyPrincipal) user).isAuthenticated();
246: } else {
247: logger.log(BasicLevel.ERROR, "The user '" + user
248: + "' is not instance of JettyPrincipal");
249: return false;
250: }
251: }
252:
253: /**
254: * Gets the principal with the given username
255: * @param username the given username
256: * @return the principal with the given username
257: */
258: public Principal getPrincipal(String username) {
259: if (logger.isLoggable(BasicLevel.DEBUG)) {
260: logger.log(BasicLevel.DEBUG,
261: "Get principal with username '" + username + "'.");
262: }
263:
264: JettyPrincipal principal = (JettyPrincipal) users.get(username);
265: SecurityContext ctx = new SecurityContext(principal.getName(),
266: principal.getRoles());
267: SecurityCurrent current = SecurityCurrent.getCurrent();
268: current.setSecurityContext(ctx);
269: return principal;
270: }
271:
272: /**
273: * Disassociate a user Not implemented
274: * @param user the given user
275: */
276: public void disassociate(Principal user) {
277: }
278:
279: /**
280: * Push a role to a user Not implemented
281: * @param user the given user
282: * @param role the role to push
283: * @return the new principal
284: */
285: public Principal pushRole(Principal user, String role) {
286: return user;
287: }
288:
289: /**
290: * Pop a role to a user Not implemented
291: * @param user the given user
292: * @return the new principal
293: */
294: public Principal popRole(Principal user) {
295: return user;
296: }
297:
298: /**
299: * Log out a specific user
300: * @param user the user to logout
301: */
302: public void logout(Principal user) {
303: }
304:
305: /**
306: * Check if the specific user is authenticated
307: * @param user the user to reauthenticate
308: * @return true if the user is authenthicated
309: */
310: public boolean reauthenticate(Principal user) {
311: if (user instanceof JettyPrincipal) {
312: return ((JettyPrincipal) user).isAuthenticated();
313: } else {
314: return false;
315: }
316: }
317:
318: /**
319: * @return the logger.
320: */
321: protected static Logger getLogger() {
322: return logger;
323: }
324:
325: /**
326: * @return the users.
327: */
328: protected Map getUsers() {
329: return users;
330: }
331:
332: /**
333: * Remove a specific user
334: * @param username user to remove
335: */
336: protected void removeUser(String username) {
337: users.remove(username);
338: }
339:
340: /**
341: * Add a user to the current map
342: * @param username name of the user
343: * @param principal object
344: */
345: protected void addUser(String username, Principal principal) {
346: users.put(username, principal);
347: }
348:
349: /**
350: * Sets the name of the realm
351: * @param name The name to set.
352: */
353: protected void setName(String name) {
354: this.name = name;
355: }
356: }
|