KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jguard > ext > authentication > manager > AbstractAuthenticationManager


1 /*
2 jGuard is a security framework based on top of jaas (java authentication and authorization security).
3 it is written for web applications, to resolve simply, access control problems.
4 version $Name$
5 http://sourceforge.net/projects/jguard/
6
7 Copyright (C) 2004 Charles GAY
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23
24 jGuard project home page:
25 http://sourceforge.net/projects/jguard/
26
27 */

28 package net.sf.jguard.ext.authentication.manager;
29
30 import java.io.IOException JavaDoc;
31 import java.io.OutputStream JavaDoc;
32 import java.security.Principal JavaDoc;
33 import java.util.Collection JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.HashSet JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Random JavaDoc;
39 import java.util.Set JavaDoc;
40 import java.util.logging.Level JavaDoc;
41 import java.util.logging.Logger JavaDoc;
42
43 import javax.security.auth.Subject JavaDoc;
44
45 import net.sf.jguard.core.authentication.credentials.JGuardCredential;
46 import net.sf.jguard.core.principals.RolePrincipal;
47 import net.sf.jguard.core.principals.UserPrincipal;
48 import net.sf.jguard.ext.SecurityConstants;
49 import net.sf.jguard.ext.authentication.AuthenticationException;
50 import net.sf.jguard.ext.principals.PrincipalUtils;
51 import net.sf.jguard.ext.registration.RegistrationException;
52 import net.sf.jguard.ext.registration.SubjectTemplate;
53 import net.sf.jguard.ext.util.SubjectUtils;
54
55
56 /**
57  * Abstract class which provides convenient methods for all the
58  * AuthenticationManager implementations.
59  * @author <a HREF="mailto:diabolo512@users.sourceforge.net">Charles Gay</a>
60  * @author <a HREF="mailto:tandilero@users.sourceforge.net">Maximiliano Batelli</a>
61  */

62 public abstract class AbstractAuthenticationManager implements AuthenticationManager {
63
64     private static final Logger JavaDoc logger = Logger.getLogger(AbstractAuthenticationManager.class.getName());
65     protected static final String JavaDoc DEFAULT = "default";
66     protected SubjectTemplate subjectTemplate;
67     protected boolean debug = false;
68
69     protected String JavaDoc applicationName;
70
71
72
73     //principals owned by the application
74
protected Set JavaDoc localPrincipalsSet;
75     protected Map JavaDoc localPrincipals;
76
77     public AbstractAuthenticationManager() {
78         super();
79
80         localPrincipalsSet= new HashSet JavaDoc();
81         localPrincipals = new HashMap JavaDoc();
82     }
83
84     
85
86     /**
87      * verify the Subject and create a user in the XML backend.
88      * @param user Subject to create in the XML backend
89      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#createUser(javax.security.auth.Subject)
90      */

91     public Subject JavaDoc createUser(SubjectTemplate user) throws RegistrationException {
92         return createUser(user,this.subjectTemplate);
93     }
94
95     /**
96      * verify the Subject against the provided template and create a user in the XML backend.
97      * @param user Subject to create in the XML backend
98      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#createUser(javax.security.auth.Subject)
99      * @throws AuthenticationException if user already exists
100      */

101     public Subject JavaDoc createUser(SubjectTemplate user,SubjectTemplate template) throws RegistrationException {
102         Subject JavaDoc userCreated = null;
103         if(template!= null){
104             //validate credentials of the SubjectTemplate
105
template.validateUser(user);
106             userCreated = template.buildSubject(user);
107         }else{
108             userCreated = user.toSubject();
109         }
110
111         try{
112             if(!userAlreadyExists(userCreated)){
113                 //persist the user in the corresponding datasource backend
114
persistUser(userCreated);
115             }else{
116                 throw new RegistrationException(" user already exists ");
117             }
118         }catch(AuthenticationException e){
119             throw new RegistrationException(e);
120         }
121
122         logger.finest(" user persisted \n");
123         return userCreated;
124     }
125
126     /**
127      * verify the Subject and create a user in the XML backend.
128      * @param user Subject to create in the XML backend
129      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#createUser(javax.security.auth.Subject)
130      */

131     public void createUser(Subject JavaDoc user) throws AuthenticationException {
132         Set JavaDoc missingCredentials = null;
133         if(subjectTemplate!= null){
134         //we remove unknown credential and return missing credentials
135
missingCredentials = subjectTemplate.validateRequiredCredentialsFromUser(user);
136         }else{
137             missingCredentials = new HashSet JavaDoc();
138         }
139         //we remove unknown credentials
140
user.getPrincipals(RolePrincipal.class).retainAll(localPrincipalsSet);
141         if(missingCredentials.size()==0){
142             persistUser(user);
143         }else{
144             throw new AuthenticationException(" the user cannot be created :some credentials are missing "+missingCredentials);
145         }
146     }
147
148     /**
149      * create a Principal in the backend, <strong>only</strong> if it is not already present.
150      * @param principal Principal to create in the backend
151      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#createPrincipal(javax.security.auth.Subject)
152      */

153     public void createPrincipal(Principal JavaDoc principal) throws AuthenticationException {
154         if(!localPrincipalsSet.contains(principal)){
155             localPrincipalsSet.add(principal);
156             localPrincipals.put(principal.getName(),principal);
157             persistPrincipal(principal);
158         }
159     }
160
161     /**
162      * persist user in the datasource backend.
163      * @param user
164      */

165     protected abstract void persistUser(Subject JavaDoc user)throws AuthenticationException;
166
167     /**
168      * persist role in the datasource backend.
169      * @param principal to persist
170      */

171     protected abstract void persistPrincipal(Principal JavaDoc principal) throws AuthenticationException;
172
173
174
175
176     /**
177      * get the principals defined in the repository for all the applications.
178      * @return role's list.
179      *
180      */

181     public Set JavaDoc getLocalPrincipals(){
182         return localPrincipalsSet;
183     }
184
185     /**
186      * retrieve role from the principals set of the webapp.
187      * @param name
188      * @return role found or null if not found
189      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#getRole(java.lang.String)
190      */

191     public Principal JavaDoc getLocalPrincipal(String JavaDoc name) throws AuthenticationException {
192         Principal JavaDoc ppal = (Principal JavaDoc)localPrincipals.get(name);
193         if(ppal instanceof RolePrincipal)
194             return (Principal JavaDoc)((RolePrincipal)ppal).clone();
195         
196         return null;
197     }
198
199     /**
200      * indicate wether the user exists in the webapp or not.
201      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#userAlreadyExists(javax.security.auth.Subject)
202      * @param user we are looking for
203      * @return true if registered in the webapp, false otherwise
204      */

205     public boolean userAlreadyExists(Subject JavaDoc user) throws AuthenticationException {
206         Set JavaDoc credentialsFromSubject = new HashSet JavaDoc();
207         JGuardCredential identityCred = extractIdentityCredentialFromUser(user);
208         credentialsFromSubject.add(identityCred);
209         Collection JavaDoc usersFound = findUsers(credentialsFromSubject);
210         if (usersFound.size()>0){
211             return true;
212         }
213         return false;
214     }
215
216     /**
217      * add a role present in the webapp to the registered user.
218      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#addPrincipalToUser(javax.security.auth.Subject, java.lang.String)
219      */

220     public void addPrincipalToUser(Subject JavaDoc user, String JavaDoc roleName) throws AuthenticationException {
221         Principal JavaDoc role = (Principal JavaDoc)localPrincipals.get(roleName);
222         if(role==null){
223             throw new AuthenticationException(" role "+roleName+" does not exists in the current web application ");
224         }
225         JGuardCredential identityCred = extractIdentityCredentialFromUser(user);
226         user.getPrincipals().add(role);
227         //we update connected users
228
updateUser(identityCred,user);
229     }
230
231     /**
232      * add a role present in the webapp to the registered user.
233      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#addPrincipalToUser(javax.security.auth.Subject, java.lang.String)
234      */

235     public void addPrincipalToUser(Subject JavaDoc user, String JavaDoc roleName,String JavaDoc applicationName) throws AuthenticationException {
236         Principal JavaDoc role = new RolePrincipal(roleName,applicationName);
237         JGuardCredential identityCred = extractIdentityCredentialFromUser(user);
238         user.getPrincipals().add(role);
239         //we update connected users
240
updateUser(identityCred,user);
241     }
242
243
244     /**
245      * verify whether or not the role exists in the webapp.
246      * @param role
247      */

248     public boolean hasPrincipal(Principal JavaDoc role) throws AuthenticationException {
249         return localPrincipalsSet.contains(role);
250     }
251
252     /**
253      * verify whether or not the role exists in the webapp.
254      * @param ppalName Principal's name
255      */

256     public boolean hasPrincipal(String JavaDoc ppalName) throws AuthenticationException {
257         Iterator JavaDoc itPrincipals = localPrincipalsSet.iterator();
258         while(itPrincipals.hasNext()){
259             Principal JavaDoc ppal = (Principal JavaDoc)itPrincipals.next();
260             if(ppal.getName().equals(ppalName)){
261                 return true;
262             }
263         }
264         return false;
265     }
266
267     public void updateUser(JGuardCredential identityCred,Subject JavaDoc user)throws AuthenticationException{
268         // remove non-persistant principals
269
Set JavaDoc principals = user.getPrincipals();
270         Set JavaDoc userPrincipals = user.getPrincipals(UserPrincipal.class);
271         boolean userPrincipalFound = false;
272         Iterator JavaDoc itJexlPrincipals = userPrincipals.iterator();
273         while(itJexlPrincipals.hasNext()){
274             Principal JavaDoc userPrincipal = (Principal JavaDoc) itJexlPrincipals.next();
275             principals.remove(userPrincipal);
276             userPrincipalFound = true;
277         }
278
279         updateUserImpl(identityCred, user);
280
281         // add updated userPrincipal (only if was created previously)
282
if(userPrincipalFound)
283             user.getPrincipals().add(new UserPrincipal(user));
284     }
285
286     protected abstract void updateUserImpl(JGuardCredential identityCred,Subject JavaDoc user)throws AuthenticationException;
287
288
289     /**
290      * search the users which matches credentials criterions.
291      * @param credentials crierions used to grab the users
292      * @return users found
293      */

294     public abstract Set JavaDoc findUsers(Collection JavaDoc credentials) throws AuthenticationException;
295
296
297     /**
298      * return the default <strong>unmodifiable</strong> SubjectTemplate.
299      * @return default unmodifiable SubjectTemplate
300      * @throws AuthenticationException
301      */

302     public SubjectTemplate getDefaultSubjectTemplate() throws AuthenticationException{
303         if(subjectTemplate==null){
304             subjectTemplate = getSubjectTemplate(DEFAULT);
305         }
306         return subjectTemplate.unmodifiableSubjectTemplate();
307     }
308
309
310     public abstract Set JavaDoc getUsers() throws AuthenticationException;
311
312
313     public void importAuthenticationManager(AuthenticationManager authManager){
314         if(authManager.isEmpty()){
315             logger.warning(" authManager to import is empty ");
316             return;
317         }
318
319         //import global principals
320
Set JavaDoc ppals = null;
321         try {
322             ppals = authManager.getAllPrincipalsSet();
323         } catch (AuthenticationException e) {
324             logger.log(Level.SEVERE, " principals cannot be grabbed : ", e);
325         }
326         Iterator JavaDoc itPrincipals = ppals.iterator();
327         while(itPrincipals.hasNext()){
328             Principal JavaDoc ppal = (Principal JavaDoc)itPrincipals.next();
329             try {
330                 createPrincipal(ppal);
331             } catch (AuthenticationException e) {
332                 logger.log(Level.SEVERE, " principal cannot persisted : ", e);
333             }
334         }
335
336         //import users
337
Set JavaDoc usersSet;
338         try {
339             usersSet = authManager.getUsers();
340         Iterator JavaDoc itUsers = usersSet.iterator();
341         while(itUsers.hasNext()){
342            Subject JavaDoc user = (Subject JavaDoc)itUsers.next();
343                 persistUser(user);
344             }
345
346             SubjectTemplate st = authManager.getDefaultSubjectTemplate();
347
348             this.persistSubjectTemplate(st);
349             this.subjectTemplate = st;
350         } catch (AuthenticationException e) {
351             logger.log(Level.SEVERE, " default subject template cannot be persisted : ", e);
352         }
353
354     }
355
356
357     /**
358      * extract credentials sought
359      * @param credentialsSought
360      * @param credentials
361      * @return
362      */

363     protected Set JavaDoc extractCredentials(Set JavaDoc credentialsSought, Set JavaDoc credentials) {
364          Set JavaDoc credentialsFromSubject = new HashSet JavaDoc();
365         Iterator JavaDoc itCred = credentials.iterator();
366         while(itCred.hasNext()){
367             JGuardCredential cred = (JGuardCredential)itCred.next();
368             String JavaDoc credId = cred.getId();
369             Iterator JavaDoc itCredInvolved = credentialsSought.iterator();
370             while(itCredInvolved.hasNext()){
371                 JGuardCredential credInvolved = (JGuardCredential)itCredInvolved.next();
372                 if(credInvolved.getId().equals(credId)){
373                     credentialsFromSubject.add(cred);
374                 }
375             }
376         }
377         return credentialsFromSubject;
378     }
379
380     protected Set JavaDoc extractCredentialsFromSubject(Set JavaDoc credentialsSought,Subject JavaDoc user){
381          Set JavaDoc credentialsFromSubject = new HashSet JavaDoc();
382          credentialsFromSubject.addAll(extractCredentials(credentialsSought,user.getPublicCredentials(JGuardCredential.class)));
383          credentialsFromSubject.addAll(extractCredentials(credentialsSought,user.getPrivateCredentials(JGuardCredential.class)));
384          return credentialsFromSubject;
385     }
386
387     protected JGuardCredential extractIdentityCredentialFromUser(Subject JavaDoc user) throws AuthenticationException{
388         Set JavaDoc creds = new HashSet JavaDoc();
389         creds.add(this.subjectTemplate.getIdentityCredential());
390          Set JavaDoc credsFound = extractCredentialsFromSubject(creds,user);
391          if(credsFound.size()>1){
392              throw new IllegalArgumentException JavaDoc(" the user has got more than one identity argument ");
393          }else if (credsFound.size()<1){
394              throw new IllegalArgumentException JavaDoc(" the user has'nt got one identity argument ");
395          }else{
396              return (JGuardCredential)credsFound.iterator().next();
397          }
398     }
399
400     /**
401      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#clonePrincipal(String roleName)
402      */

403     public Principal JavaDoc clonePrincipal(String JavaDoc roleName) throws AuthenticationException {
404         Random JavaDoc rnd = new Random JavaDoc();
405         String JavaDoc cloneName = roleName+rnd.nextInt(99999);
406
407         return clonePrincipal(roleName, cloneName);
408     }
409
410     /**
411      * @see net.sf.jguard.ext.authentication.manager.AuthenticationManager#clonePrincipal(String roleName, String cloneName)
412      */

413     public Principal JavaDoc clonePrincipal(String JavaDoc roleName, String JavaDoc cloneName) throws AuthenticationException {
414         Principal JavaDoc role = (Principal JavaDoc)localPrincipals.get(roleName);
415         Principal JavaDoc clone = null;
416         if(role instanceof RolePrincipal) {
417             clone = (RolePrincipal)((RolePrincipal)role).clone();
418             ((RolePrincipal)clone).setName(cloneName);
419         }
420         else
421             clone = PrincipalUtils.getPrincipal(role.getClass().getName(), cloneName);
422
423         //persist the newly created clone
424
createPrincipal(clone);
425
426     return clone;
427     }
428     
429     /**
430      * change 'active' property on the specified role for a user.
431      * this change cannot be done on 'guest' user, or if it remains only one 'active=true' role.
432      * @param subject
433      * @param roleName
434      * @param applicationName
435      * @param active
436      * @throws AuthenticationException
437      */

438     public void setActiveOnRolePrincipal(Subject JavaDoc subject,String JavaDoc roleName,String JavaDoc applicationName,boolean active) throws AuthenticationException{
439         //guest users cannot change their 'guest' role.
440
if(roleName.equals(SecurityConstants.GUEST)){
441             throw new AuthenticationException(SecurityConstants.GUEST+" 'active' property cannot be modified ");
442         }
443         JGuardCredential identityCredential = extractIdentityCredentialFromUser(subject);
444         if(!active && !checkMultipleActiveRoleExists(subject)){
445             throw new AuthenticationException("only one role is active from the same application. user cannot inactivate it ");
446         }
447         Principal JavaDoc principal = getRole(subject, roleName, applicationName);
448         if(principal instanceof RolePrincipal){
449             RolePrincipal role = (RolePrincipal)principal;
450             role.setActive(active);
451             updateUser(identityCredential, subject);
452         }else{
453             logger.warning("active can only be applied to RolePrincipal");
454         }
455     }
456     
457     public Principal JavaDoc getRole(Subject JavaDoc subject,String JavaDoc roleName,String JavaDoc applicationName) throws AuthenticationException{
458         if(roleName == null || roleName.equals("")){
459             throw new AuthenticationException("roleName is null or empty");
460         }
461         if(applicationName == null || applicationName.equals("")){
462             throw new AuthenticationException("applicationName is null or empty");
463         }
464         Set JavaDoc principals = subject.getPrincipals();
465         Iterator JavaDoc it = principals.iterator();
466         Principal JavaDoc principalFound = null;
467         while(it.hasNext()){
468             Principal JavaDoc principal = (Principal JavaDoc)it.next();
469                 if(roleName.equals(principal.getName())){
470                     principalFound = principal;
471                     break;
472                 }
473             
474         }
475         if(principalFound == null){
476             throw new AuthenticationException(" role not found ");
477         }
478         return principalFound;
479     }
480     
481     /**
482      * check that user owns multiple 'active' roles from the <u>same</u> application.
483      * @param subject
484      * @return
485      */

486     private boolean checkMultipleActiveRoleExists(Subject JavaDoc subject){
487         Set JavaDoc principals = subject.getPrincipals();
488         Iterator JavaDoc it = principals.iterator();
489         int activeRoles = 0;
490         while(it.hasNext()){
491             Principal JavaDoc principal = (Principal JavaDoc)it.next();
492             
493             if(principal instanceof RolePrincipal){
494                 RolePrincipal rPrincipal =null;
495                 rPrincipal = (RolePrincipal)principal;
496                 if(rPrincipal.isActive() && this.applicationName.equals(rPrincipal.getApplicationName())){
497                     activeRoles++;
498                 }
499             }
500             
501         }
502         if(activeRoles>1){
503             return true;
504         }
505         return false;
506     }
507
508     /**
509      * finds an user.
510      * @param login
511      * @param am
512      * @return Subject
513      */

514     public Subject JavaDoc findUser(String JavaDoc login) {
515         Set JavaDoc credentials = new HashSet JavaDoc();
516         JGuardCredential jcred = new JGuardCredential();
517         jcred.setId("login");
518         jcred.setValue(login);
519         credentials.add(jcred);
520
521         Subject JavaDoc user = null;
522         try {
523             Collection JavaDoc usersFound = findUsers(credentials);
524             Iterator JavaDoc itUsers = usersFound.iterator();
525             if(itUsers.hasNext()){
526                 user = (Subject JavaDoc)itUsers.next();
527             }else{
528                 throw new AuthenticationException(" no user found ");
529             }
530         } catch (AuthenticationException e) {
531             logger.log(Level.WARNING, e.getLocalizedMessage());
532         }
533
534         return user;
535     }
536     
537     public void updateRoleDefinition(Subject JavaDoc subject, String JavaDoc roleName,String JavaDoc applicationName,String JavaDoc definition) throws AuthenticationException {
538            RolePrincipal ppal = (RolePrincipal)getRole(subject,roleName,applicationName);
539            ppal.setDefinition(definition);
540            JGuardCredential identity = SubjectUtils.getIdentityCredential(subject, AuthenticationManagerFactory.getAuthenticationManager().getDefaultSubjectTemplate());
541            AuthenticationManagerFactory.getAuthenticationManager().updateUser(identity, subject);
542
543     }
544
545 }
546
Popular Tags