KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > authentication > impl > UserAuthenticatorImpl


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.authentication.impl;
17
18 import org.outerj.daisy.authentication.UserAuthenticator;
19 import org.outerj.daisy.authentication.AuthenticationException;
20 import org.outerj.daisy.authentication.AuthenticationScheme;
21 import org.outerj.daisy.authentication.AuthenticationSchemeRegistrar;
22 import org.outerj.daisy.repository.commonimpl.AuthenticatedUser;
23 import org.outerj.daisy.repository.commonimpl.AuthenticatedUserImpl;
24 import org.outerj.daisy.repository.commonimpl.user.AuthenticationSchemeInfoImpl;
25 import org.outerj.daisy.repository.commonimpl.user.AuthenticationSchemeInfosImpl;
26 import org.outerj.daisy.repository.Credentials;
27 import org.outerj.daisy.repository.AuthenticationFailedException;
28 import org.outerj.daisy.repository.RepositoryException;
29 import org.outerj.daisy.repository.user.*;
30 import org.apache.avalon.framework.logger.AbstractLogEnabled;
31 import org.apache.avalon.framework.service.Serviceable;
32 import org.apache.avalon.framework.service.ServiceManager;
33 import org.apache.avalon.framework.service.ServiceException;
34 import org.apache.avalon.framework.activity.Initializable;
35 import org.apache.avalon.framework.configuration.Configurable;
36 import org.apache.avalon.framework.configuration.Configuration;
37 import org.apache.avalon.framework.configuration.ConfigurationException;
38 import org.apache.commons.collections.primitives.LongList;
39 import org.apache.commons.collections.primitives.ArrayLongList;
40
41 import java.util.Map JavaDoc;
42 import java.util.Iterator JavaDoc;
43
44 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
45
46 import javax.management.MBeanServer JavaDoc;
47 import javax.management.ObjectName JavaDoc;
48
49 /**
50  * Default, database-based implementation of the {@link UserAuthenticator} interface.
51  *
52  * @avalon.component version="1.0" name="user-authenticator" lifestyle="singleton"
53  * @avalon.service type="org.outerj.daisy.authentication.UserAuthenticator"
54  * @avalon.service type="org.outerj.daisy.authentication.AuthenticationSchemeRegistrar"
55  */

56 public class UserAuthenticatorImpl extends AbstractLogEnabled implements UserAuthenticator, UserAuthenticatorImplMBean,
57         AuthenticationSchemeRegistrar, Serviceable, Initializable, Configurable {
58     private UserManager userManager;
59     private Map JavaDoc schemes = new ConcurrentReaderHashMap();
60     private AuthenticationSchemeInfos authenticationSchemeInfos = new AuthenticationSchemeInfosImpl(new AuthenticationSchemeInfo[0]);
61     private ServiceManager serviceManager;
62     private String JavaDoc schemeForUserCreation;
63
64     /**
65      * @avalon.dependency key="mbeanserver" type="javax.management.MBeanServer"
66      */

67     public void service(ServiceManager serviceManager) throws ServiceException {
68         this.serviceManager = serviceManager;
69     }
70
71     public void configure(Configuration configuration) throws ConfigurationException {
72         Configuration schemeForUserCreationConf = configuration.getChild("authenticationSchemeForUserCreation", false);
73         if (schemeForUserCreationConf != null) {
74             schemeForUserCreation = schemeForUserCreationConf.getValue();
75         }
76     }
77
78     public void initialize() throws Exception JavaDoc {
79         MBeanServer JavaDoc mbeanServer = (MBeanServer JavaDoc)serviceManager.lookup("mbeanserver");
80         try {
81             mbeanServer.registerMBean(this, new ObjectName JavaDoc("Daisy:name=UserAuthenticator"));
82         } finally {
83             serviceManager.release(mbeanServer);
84         }
85     }
86
87     public void setUserManager(UserManager userManager) {
88         this.userManager = userManager;
89     }
90
91     public AuthenticatedUser authenticate(Credentials credentials) throws RepositoryException {
92
93         // Handle the special case of the user $system
94
if (credentials.getLogin().equals("$system")) {
95             throw new AuthenticationException("User $system is an internally used user that can not log in.");
96         }
97
98         if (userManager == null) {
99             throw new AuthenticationException("Got a request for authentication before being supplied with a UserManager instance.");
100         }
101
102         // Get the user (will throw an exception if the user does not exist)
103
User user = null;
104         try {
105             user = userManager.getUser(credentials.getLogin(), false);
106         } catch (UserNotFoundException e) {
107             if (schemeForUserCreation != null) {
108                 AuthenticationScheme scheme = (AuthenticationScheme)schemes.get(schemeForUserCreation);
109                 if (scheme != null) {
110                     user = scheme.createUser(credentials, userManager);
111                 }
112             }
113             if (user == null)
114                 throw e;
115         }
116
117         // Check the user is marked as 'confirmed'
118
if (!user.isConfirmed())
119             throw new AuthenticationFailedException(credentials.getLogin());
120
121         // Check the credentials
122
AuthenticationScheme authenticationScheme = (AuthenticationScheme)schemes.get(user.getAuthenticationScheme());
123         if (authenticationScheme == null)
124             throw new AuthenticationException("The authentication scheme of the user does not exist.");
125
126         if (!authenticationScheme.check(credentials))
127             throw new AuthenticationFailedException(credentials.getLogin());
128
129         // Everything ok: user is allowed
130
long[] availableRoleIds= user.getAllRoleIds();
131         long[] activeRoleIds = determineActiveRoles(user.getDefaultRole(), availableRoleIds);
132         return new AuthenticatedUserImpl(user.getId(), null, activeRoleIds, availableRoleIds, user.getLogin());
133     }
134
135     /**
136      * The active roles are either: the default role if any, otherwise all roles except
137      * the administrator role, except if Administrator would be the only role.
138      */

139     private long[] determineActiveRoles(Role defaultRole, long[] availableRoleIds) {
140         if (defaultRole != null)
141             return new long[] {defaultRole.getId()};
142         if (availableRoleIds.length == 1)
143             return availableRoleIds;
144
145         LongList roleIds = new ArrayLongList(availableRoleIds.length);
146         for (int i = 0; i < availableRoleIds.length; i++) {
147             if (availableRoleIds[i] != Role.ADMINISTRATOR)
148                 roleIds.add(availableRoleIds[i]);
149         }
150         return roleIds.toArray();
151     }
152
153     public AuthenticationSchemeInfos getAuthenticationSchemes() {
154         return authenticationSchemeInfos;
155     }
156
157     public synchronized void registerAuthenticationScheme(AuthenticationScheme scheme) {
158         String JavaDoc name = scheme.getName();
159         if (name.length() > 50)
160             throw new RuntimeException JavaDoc("The name of an authentication scheme may not exceed 50 characters.");
161         if (schemes.containsKey(name))
162             throw new RuntimeException JavaDoc("There is already an authentication scheme named \"" + name + "\" registered.");
163         if (schemes.containsValue(scheme))
164             throw new RuntimeException JavaDoc("The provided AuthenticationScheme object is already registered.");
165
166         schemes.put(name, scheme);
167         rebuildAuthenticationSchemeInfos();
168     }
169
170     public synchronized void unregisterAuthenticationScheme(AuthenticationScheme scheme) {
171         String JavaDoc key = null;
172         Iterator JavaDoc entryIt = schemes.entrySet().iterator();
173         while (entryIt.hasNext()) {
174             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)entryIt.next();
175             if (entry.getValue() == scheme) {
176                 key = (String JavaDoc)entry.getKey();
177                 break;
178             }
179         }
180         if (key != null) {
181             schemes.remove(key);
182             rebuildAuthenticationSchemeInfos();
183         }
184     }
185
186     private void rebuildAuthenticationSchemeInfos() {
187         AuthenticationSchemeInfo[] infos = new AuthenticationSchemeInfo[schemes.size()];
188         Iterator JavaDoc schemesIt = this.schemes.values().iterator();
189         int i = 0;
190         while (schemesIt.hasNext()) {
191             AuthenticationScheme scheme = (AuthenticationScheme)schemesIt.next();
192             infos[i] = new AuthenticationSchemeInfoImpl(scheme.getName(), scheme.getDescription());
193             i++;
194         }
195         this.authenticationSchemeInfos = new AuthenticationSchemeInfosImpl(infos);
196     }
197
198     public synchronized void clearPasswordCaches() {
199         Iterator JavaDoc schemesIt = schemes.values().iterator();
200         while (schemesIt.hasNext()) {
201             AuthenticationScheme scheme = (AuthenticationScheme)schemesIt.next();
202             scheme.clearCaches();
203         }
204     }
205 }
206
Popular Tags