User: starksm
Date: 01/07/09 01:49:37
Modified: src/main/org/jboss/security/plugins Tag: Branch_2_4
JaasSecurityManager.java
Log:
Add support for authenticating anonymous users(username, password == null)
at the UsernamePasswordLoginModule level and update JaasSecurityManager to
provide a callerPrincipal for the case of a null principal.
Revision Changes Path
No revision
No revision
1.7.2.1 +472 -446
jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManager.java
Index: JaasSecurityManager.java
===================================================================
RCS file:
/cvsroot/jboss/jbosssx/src/main/org/jboss/security/plugins/JaasSecurityManager.java,v
retrieving revision 1.7
retrieving revision 1.7.2.1
diff -u -r1.7 -r1.7.2.1
--- JaasSecurityManager.java 2001/06/15 08:26:02 1.7
+++ JaasSecurityManager.java 2001/07/09 08:49:37 1.7.2.1
@@ -1,446 +1,472 @@
-/*
- * JBoss, the OpenSource EJB server
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.security.plugins;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Set;
-
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.acl.Group;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.security.auth.Policy;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.jboss.security.AppPolicy;
-import org.jboss.security.AuthenticationInfo;
-import org.jboss.security.EJBSecurityManager;
-import org.jboss.security.RealmMapping;
-import org.jboss.security.SecurityAssociation;
-import org.jboss.security.SecurityPolicy;
-import org.jboss.security.SimplePrincipal;
-import org.jboss.security.SubjectSecurityManager;
-import org.jboss.security.auth.callback.SecurityAssociationHandler;
-import org.jboss.util.CachePolicy;
-import org.jboss.util.TimedCachePolicy;
-
-/** The JaasSecurityManager is responsible both for authenticating credentials
-associated with principals and for role mapping. This implementation relies
-on the JAAS LoginContext/LoginModules associated with the security
-domain name associated with the class for authentication,
-and the context JAAS Subject object for role mapping.
-
-@see #isValid(Principal, Object)
-@see #Principal getPrincipal(Principal)
-@see #doesUserHaveRole(Principal, Set)
-
-@author <a href="[EMAIL PROTECTED]">Oleg Nitz</a>
-@author [EMAIL PROTECTED]
-@version $Revision: 1.7 $
-*/
-public class JaasSecurityManager implements SubjectSecurityManager, RealmMapping
-{
- /** The authentication cache object.
- */
- public static class DomainInfo
- {
- Subject subject;
- Object credential;
- Principal callerPrincipal;
- Group roles;
- }
-
- /** The current authenticate()d subject.
- */
- private static ThreadLocal activeSubject = new ThreadLocal();
- /** The name of the domain this instance is securing. It is used as
- the appName into the SecurityPolicy.
- */
- private String securityDomain;
- /** A cache of DomainInfo objects keyd by Principal.
- */
- private CachePolicy domainCache;
- /** The custom JAAS policy. This may be null if a custom
- policy is not being used.
- */
- private SecurityPolicy securityPolicy;
- /** Used in the absence of a SecurityPolicy specific CallbackHandler
- to pass credential info to the LoginModule associated with the
- securityDomain name.
- */
- private SecurityAssociationHandler handler = new SecurityAssociationHandler();
-
- /** Get the currently authenticated Subject in securityDomain.
- @return The Subject for securityDomain if one exists, false otherwise.
- */
- public static Subject getActiveSubject(String securityDomain)
- {
- Subject subject = null;
- try
- {
- InitialContext ctx = new InitialContext();
- String jsmName = "jaas:/"+securityDomain;
- JaasSecurityManager jsm = (JaasSecurityManager) ctx.lookup(jsmName);
- subject = jsm.getActiveSubject();
- }
- catch(NamingException e)
- {
- }
- return subject;
- }
- /** Create a LoginContext for the currently authenticated Subject in
- securityDomain.
- */
- public static LoginContext getActiveSubjectLoginContext(String securityDomain,
CallbackHandler handler)
- throws LoginException
- {
- LoginContext lc = null;
- Subject subject = getActiveSubject(securityDomain);
- if( subject == null )
- throw new LoginException("No active subject found in securityDomain:
"+securityDomain);
-
- if( handler != null )
- lc = new LoginContext(securityDomain, subject, handler);
- else
- lc = new LoginContext(securityDomain, subject);
-
- return lc;
- }
-
- /** Creates a default JaasSecurityManager for with a securityDomain
- name of 'other'.
- */
- public JaasSecurityManager()
- {
- this("other");
- }
- /** Creates a JaasSecurityManager for with a securityDomain
- name of that given by the 'securityDomain' argument.
- @param securityDomain.
- */
- public JaasSecurityManager(String securityDomain)
- {
- this.securityDomain = securityDomain;
- try
- { // Try to get the SecurityPolicy from the JAAS Policy class
- securityPolicy = (SecurityPolicy) Policy.getPolicy();
- }
- catch(ClassCastException e)
- { // The installed Policy is not a SecurityPolicy
- }
- }
-
- /** The domainCache is typically a shared object that is populated
- by the login code(LoginModule, etc.) and read by this class in the
- isValid() method.
- @see #isValid(Principal, Object)
- */
- public void setCachePolicy(CachePolicy domainCache)
- {
- this.domainCache = domainCache;
- }
-
- public void flushCache()
- {
- if( domainCache != null )
- domainCache.flush();
- }
-
- public void setSecurityPolicyName(String jndiName) throws NamingException
- {
- InitialContext ctx = new InitialContext();
- securityPolicy = (SecurityPolicy) ctx.lookup(jndiName);
- }
-
- /** Get the name of the security domain associated with this security mgr.
- @return Name of the security manager security domain.
- */
- public String getSecurityDomain()
- {
- return securityDomain;
- }
- /** Get the currently authenticated Subject. This is a thread local
- property shared across all JaasSecurityManager instances.
- @return The Subject authenticated in the current thread if one
- exists, null otherwise.
- */
- public Subject getActiveSubject()
- {
- return (Subject) activeSubject.get();
- }
-
- /** Validate that the given credential is correct for principal. This first
- will check the current CachePolicy object if one exists to see if the
- user's cached credentials match the given credential. If there is no
- credential cache or the cache information is invalid or does not match,
- the user is authenticated against the JAAS login modules configured for
- the security domain.
- @param principal, the security domain principal attempting access
- @param credential, the proof of identity offered by the principal
- @return true if the principal was authenticated, false otherwise.
- */
- public boolean isValid(Principal principal, Object credential)
- {
- // Check the cache first
- DomainInfo cacheInfo = null;
- if( domainCache != null )
- cacheInfo = (DomainInfo) domainCache.get(principal);
-
- boolean isValid = false;
- if( cacheInfo != null )
- isValid = validateCache(cacheInfo, credential);
- if( isValid == false )
- isValid = authenticate(principal, credential);
- return isValid;
- }
-
- /** Map the argument principal from the deployment environment principal
- to the developer environment. This is called by the EJB context
- getCallerPrincipal() to return the Principal as described by
- the EJB developer domain.
- @return a Principal object that is valid in the deployment environment
- if one exists. If no Subject exists or the Subject has no principals
- then the argument principal is returned.
- */
- public Principal getPrincipal(Principal principal)
- {
- Principal result = principal;
- if( domainCache != null )
- {
- // Get the CallerPrincipal group member
- DomainInfo info = (DomainInfo) domainCache.get(principal);
- if( info != null )
- result = info.callerPrincipal;
- // If the mapping did not have a callerPrincipal just use principal
- if( result == null )
- result = principal;
- }
-
- return result;
- }
-
- /** Does the current Subject have a role(a Principal) that equates to one
- of the role names. This method obtains the Group named 'Roles' from
- the principal set of the currently authenticated Subject and then
- creates a SimplePrincipal for each name in roleNames. If the role is
- a member of the Roles group, then the user has the role.
- @param principal, ignored. The current authenticated Subject determines
- the active user and assigned user roles.
- @param rolePrincipals, a Set of Principals for the roles to check.
-
- @see java.security.acl.Group;
- @see Subject#getPrincipals()
- */
- public boolean doesUserHaveRole(Principal principal, Set rolePrincipals)
- {
- boolean hasRole = false;
- Subject subject = getActiveSubject();
- if( subject != null )
- {
- DomainInfo info = null;
- if( domainCache != null )
- info = (DomainInfo) domainCache.get(principal);
-
- Group roles = null;
- if( info != null )
- roles = info.roles;
- if( roles != null )
- {
- Iterator iter = rolePrincipals.iterator();
- while( hasRole == false && iter.hasNext() )
- {
- Principal role = (Principal) iter.next();
- hasRole = roles.isMember(role);
- }
- }
- }
- return hasRole;
- }
-
- /** Validates operational environment Principal against the specified
- application domain role.
- @param principal, the caller principal as known in the operation environment.
- @param role, the application domain role that the principal is to be validated
against.
- @return true if the principal has the role, false otherwise.
- */
- public boolean doesUserHaveRole(Principal principal, Principal role)
- {
- boolean hasRole = false;
- Subject subject = getActiveSubject();
- if( subject != null )
- {
- DomainInfo info = null;
- if( domainCache != null )
- info = (DomainInfo) domainCache.get(principal);
-
- Group roles = null;
- if( info != null )
- roles = info.roles;
- if( roles != null )
- {
- hasRole = roles.isMember(role);
- }
- }
- return hasRole;
- }
-
- /** Currently this simply calls defaultLogin() to do a JAAS login using the
- security domain name as the login module configuration name.
-
- * @param principal, the user id to authenticate
- * @param credential, an opaque credential.
- * @return false on failure, true on success.
- */
- private boolean authenticate(Principal principal, Object credential)
- {
- LoginContext lc = null;
- Subject subject = null;
- boolean authenticated = false;
-
- try
- {
- // Clear any current subject
- activeSubject.set(null);
- // Get the AppPolicy login info. Not implemented yet.
- AppPolicy policy = null;
- subject = defaultLogin(principal, credential);
-
- // Set the current subject if login was successful
- if( subject != null )
- {
- activeSubject.set(subject);
- authenticated = true;
- // Build the Subject based DomainInfo cache value
- updateCache(subject, principal, credential);
- }
- }
- catch(LoginException e)
- {
- e.printStackTrace();
- }
-
- return authenticated;
- }
-
- /** Pass the security info to the login modules configured for
- this security domain using our SecurityAssociationHandler.
- @return The authenticated Subject if successful.
- @exception LoginException throw if login fails for any reason.
- */
- private Subject defaultLogin(Principal principal, Object credential)
- throws LoginException
- {
- // We use our internal CallbackHandler to provide the security info
- handler.setSecurityInfo(principal, credential);
- Subject subject = new Subject();
- LoginContext lc = new LoginContext(securityDomain, subject, handler);
- lc.login();
- return subject;
- }
-
- /** Validate the cache credential value against the provided credential
- */
- private boolean validateCache(DomainInfo info, Object credential)
- {
- Object subjectCredential = info.credential;
- boolean isValid = false;
- if( subjectCredential.getClass().isAssignableFrom(credential.getClass()) ==
false )
- return false;
-
- if( subjectCredential instanceof Comparable )
- {
- Comparable c = (Comparable) subjectCredential;
- isValid = c.compareTo(credential) == 0;
- }
- else if( subjectCredential instanceof char[] )
- {
- char[] a1 = (char[]) subjectCredential;
- char[] a2 = (char[]) credential;
- isValid = Arrays.equals(a1, a2);
- }
- else if( subjectCredential instanceof byte[] )
- {
- byte[] a1 = (byte[]) subjectCredential;
- byte[] a2 = (byte[]) credential;
- isValid = Arrays.equals(a1, a2);
- }
- else
- {
- isValid = subjectCredential.equals(credential);
- }
-
- if( isValid )
- {
- activeSubject.set(info.subject);
- }
-
- return isValid;
- }
-
- private void updateCache(Subject subject, Principal principal, Object
credential)
- {
- DomainInfo info = new DomainInfo();
- info.subject = subject;
- info.credential = credential;
-
- /* If we don't have a cache policy create a default timed cache
- that has an 1800 sec lifetime, is thread-safe, and a resolution
- of 60 seconds.
- */
- if( domainCache == null )
- {
- domainCache = new TimedCachePolicy(1800, true, 60);
- try
- {
- domainCache.init();
- domainCache.start();
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
-
- /* Get the Subject callerPrincipal by looking for a Group called
- 'CallerPrincipal' and roles by looking for a Group called 'Roles'
- */
- Set subjectGroups = subject.getPrincipals(Group.class);
- Iterator iter = subjectGroups.iterator();
- while( iter.hasNext() )
- {
- Group grp = (Group) iter.next();
- String name = grp.getName();
- if( name.equals("CallerPrincipal") )
- {
- Enumeration members = grp.members();
- if( members.hasMoreElements() )
- info.callerPrincipal = (Principal) members.nextElement();
- }
- else if( name.equals("Roles") )
- info.roles = grp;
- }
-
- /* If the user already exists another login is active. Currently
- only one is allowed so remove the old and insert the new.
- */
- if( domainCache.peek(principal) != null )
- domainCache.remove(principal);
- domainCache.insert(principal, info);
- }
-
-}
+/*
+ * JBoss, the OpenSource EJB server
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.security.plugins;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Set;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.acl.Group;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.security.auth.Policy;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.jboss.security.AppPolicy;
+import org.jboss.security.AuthenticationInfo;
+import org.jboss.security.EJBSecurityManager;
+import org.jboss.security.RealmMapping;
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityPolicy;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.SubjectSecurityManager;
+import org.jboss.security.auth.callback.SecurityAssociationHandler;
+import org.jboss.util.CachePolicy;
+import org.jboss.util.TimedCachePolicy;
+
+/** The JaasSecurityManager is responsible both for authenticating credentials
+associated with principals and for role mapping. This implementation relies
+on the JAAS LoginContext/LoginModules associated with the security
+domain name associated with the class for authentication,
+and the context JAAS Subject object for role mapping.
+
+@see #isValid(Principal, Object)
+@see #Principal getPrincipal(Principal)
+@see #doesUserHaveRole(Principal, Set)
+
+@author <a href="[EMAIL PROTECTED]">Oleg Nitz</a>
+@author [EMAIL PROTECTED]
+@version $Revision: 1.7.2.1 $
+*/
+public class JaasSecurityManager implements SubjectSecurityManager, RealmMapping
+{
+ /** The authentication cache object.
+ */
+ public static class DomainInfo
+ {
+ Subject subject;
+ Object credential;
+ Principal callerPrincipal;
+ Group roles;
+ }
+
+ /** The current authenticate()d subject.
+ */
+ private static ThreadLocal activeSubject = new ThreadLocal();
+ /** The name of the domain this instance is securing. It is used as
+ the appName into the SecurityPolicy.
+ */
+ private String securityDomain;
+ /** A cache of DomainInfo objects keyd by Principal.
+ */
+ private CachePolicy domainCache;
+ /** The custom JAAS policy. This may be null if a custom
+ policy is not being used.
+ */
+ private SecurityPolicy securityPolicy;
+ /** Used in the absence of a SecurityPolicy specific CallbackHandler
+ to pass credential info to the LoginModule associated with the
+ securityDomain name.
+ */
+ private SecurityAssociationHandler handler = new SecurityAssociationHandler();
+
+ /** Get the currently authenticated Subject in securityDomain.
+ @return The Subject for securityDomain if one exists, false otherwise.
+ */
+ public static Subject getActiveSubject(String securityDomain)
+ {
+ Subject subject = null;
+ try
+ {
+ InitialContext ctx = new InitialContext();
+ String jsmName = "jaas:/"+securityDomain;
+ JaasSecurityManager jsm = (JaasSecurityManager) ctx.lookup(jsmName);
+ subject = jsm.getActiveSubject();
+ }
+ catch(NamingException e)
+ {
+ }
+ return subject;
+ }
+ /** Create a LoginContext for the currently authenticated Subject in
+ securityDomain.
+ */
+ public static LoginContext getActiveSubjectLoginContext(String securityDomain,
CallbackHandler handler)
+ throws LoginException
+ {
+ LoginContext lc = null;
+ Subject subject = getActiveSubject(securityDomain);
+ if( subject == null )
+ throw new LoginException("No active subject found in securityDomain:
"+securityDomain);
+
+ if( handler != null )
+ lc = new LoginContext(securityDomain, subject, handler);
+ else
+ lc = new LoginContext(securityDomain, subject);
+
+ return lc;
+ }
+
+ /** Creates a default JaasSecurityManager for with a securityDomain
+ name of 'other'.
+ */
+ public JaasSecurityManager()
+ {
+ this("other");
+ }
+ /** Creates a JaasSecurityManager for with a securityDomain
+ name of that given by the 'securityDomain' argument.
+ @param securityDomain.
+ */
+ public JaasSecurityManager(String securityDomain)
+ {
+ this.securityDomain = securityDomain;
+ try
+ { // Try to get the SecurityPolicy from the JAAS Policy class
+ securityPolicy = (SecurityPolicy) Policy.getPolicy();
+ }
+ catch(ClassCastException e)
+ { // The installed Policy is not a SecurityPolicy
+ }
+ }
+
+ /** The domainCache is typically a shared object that is populated
+ by the login code(LoginModule, etc.) and read by this class in the
+ isValid() method.
+ @see #isValid(Principal, Object)
+ */
+ public void setCachePolicy(CachePolicy domainCache)
+ {
+ this.domainCache = domainCache;
+ }
+
+ public void flushCache()
+ {
+ if( domainCache != null )
+ domainCache.flush();
+ }
+
+ public void setSecurityPolicyName(String jndiName) throws NamingException
+ {
+ InitialContext ctx = new InitialContext();
+ securityPolicy = (SecurityPolicy) ctx.lookup(jndiName);
+ }
+
+ /** Get the name of the security domain associated with this security mgr.
+ @return Name of the security manager security domain.
+ */
+ public String getSecurityDomain()
+ {
+ return securityDomain;
+ }
+ /** Get the currently authenticated Subject. This is a thread local
+ property shared across all JaasSecurityManager instances.
+ @return The Subject authenticated in the current thread if one
+ exists, null otherwise.
+ */
+ public Subject getActiveSubject()
+ {
+ return (Subject) activeSubject.get();
+ }
+
+ /** Validate that the given credential is correct for principal. This first
+ will check the current CachePolicy object if one exists to see if the
+ user's cached credentials match the given credential. If there is no
+ credential cache or the cache information is invalid or does not match,
+ the user is authenticated against the JAAS login modules configured for
+ the security domain.
+ @param principal, the security domain principal attempting access
+ @param credential, the proof of identity offered by the principal
+ @return true if the principal was authenticated, false otherwise.
+ */
+ public boolean isValid(Principal principal, Object credential)
+ {
+ // Check the cache first
+ DomainInfo cacheInfo = null;
+ if( domainCache != null )
+ cacheInfo = (DomainInfo) domainCache.get(principal);
+
+ boolean isValid = false;
+ if( cacheInfo != null )
+ isValid = validateCache(cacheInfo, credential);
+ if( isValid == false )
+ isValid = authenticate(principal, credential);
+ return isValid;
+ }
+
+ /** Map the argument principal from the deployment environment principal
+ to the developer environment. This is called by the EJB context
+ getCallerPrincipal() to return the Principal as described by
+ the EJB developer domain.
+ @return a Principal object that is valid in the deployment environment
+ if one exists. If no Subject exists or the Subject has no principals
+ then the argument principal is returned.
+ */
+ public Principal getPrincipal(Principal principal)
+ {
+ Principal result = principal;
+ if( domainCache != null )
+ {
+ // Get the CallerPrincipal group member
+ DomainInfo info = (DomainInfo) domainCache.get(principal);
+ if( info != null )
+ result = info.callerPrincipal;
+ // If the mapping did not have a callerPrincipal just use principal
+ if( result == null )
+ result = principal;
+ }
+
+ return result;
+ }
+
+ /** Does the current Subject have a role(a Principal) that equates to one
+ of the role names. This method obtains the Group named 'Roles' from
+ the principal set of the currently authenticated Subject and then
+ creates a SimplePrincipal for each name in roleNames. If the role is
+ a member of the Roles group, then the user has the role.
+ @param principal, ignored. The current authenticated Subject determines
+ the active user and assigned user roles.
+ @param rolePrincipals, a Set of Principals for the roles to check.
+
+ @see java.security.acl.Group;
+ @see Subject#getPrincipals()
+ */
+ public boolean doesUserHaveRole(Principal principal, Set rolePrincipals)
+ {
+ boolean hasRole = false;
+ Subject subject = getActiveSubject();
+ if( subject != null )
+ {
+ DomainInfo info = null;
+ if( domainCache != null )
+ info = (DomainInfo) domainCache.get(principal);
+
+ Group roles = null;
+ if( info != null )
+ roles = info.roles;
+ if( roles != null )
+ {
+ Iterator iter = rolePrincipals.iterator();
+ while( hasRole == false && iter.hasNext() )
+ {
+ Principal role = (Principal) iter.next();
+ hasRole = roles.isMember(role);
+ }
+ }
+ }
+ return hasRole;
+ }
+
+ /** Validates operational environment Principal against the specified
+ application domain role.
+ @param principal, the caller principal as known in the operation environment.
+ @param role, the application domain role that the principal is to be validated
against.
+ @return true if the principal has the role, false otherwise.
+ */
+ public boolean doesUserHaveRole(Principal principal, Principal role)
+ {
+ boolean hasRole = false;
+ Subject subject = getActiveSubject();
+ if( subject != null )
+ {
+ DomainInfo info = null;
+ if( domainCache != null )
+ info = (DomainInfo) domainCache.get(principal);
+
+ Group roles = null;
+ if( info != null )
+ roles = info.roles;
+ if( roles != null )
+ {
+ hasRole = roles.isMember(role);
+ }
+ }
+ return hasRole;
+ }
+
+ /** Currently this simply calls defaultLogin() to do a JAAS login using the
+ security domain name as the login module configuration name.
+
+ * @param principal, the user id to authenticate
+ * @param credential, an opaque credential.
+ * @return false on failure, true on success.
+ */
+ private boolean authenticate(Principal principal, Object credential)
+ {
+ LoginContext lc = null;
+ Subject subject = null;
+ boolean authenticated = false;
+
+ try
+ {
+ // Clear any current subject
+ activeSubject.set(null);
+ // Get the AppPolicy login info. Not implemented yet.
+ AppPolicy policy = null;
+ subject = defaultLogin(principal, credential);
+
+ // Set the current subject if login was successful
+ if( subject != null )
+ {
+ activeSubject.set(subject);
+ authenticated = true;
+ // Build the Subject based DomainInfo cache value
+ updateCache(subject, principal, credential);
+ }
+ }
+ catch(LoginException e)
+ {
+ e.printStackTrace();
+ }
+
+ return authenticated;
+ }
+
+ /** Pass the security info to the login modules configured for
+ this security domain using our SecurityAssociationHandler.
+ @return The authenticated Subject if successful.
+ @exception LoginException throw if login fails for any reason.
+ */
+ private Subject defaultLogin(Principal principal, Object credential)
+ throws LoginException
+ {
+ // We use our internal CallbackHandler to provide the security info
+ handler.setSecurityInfo(principal, credential);
+ Subject subject = new Subject();
+ LoginContext lc = new LoginContext(securityDomain, subject, handler);
+ lc.login();
+ return subject;
+ }
+
+ /** Validate the cache credential value against the provided credential
+ */
+ private boolean validateCache(DomainInfo info, Object credential)
+ {
+ Object subjectCredential = info.credential;
+ boolean isValid = false;
+ // Check for a null credential as can be the case for an anonymou user
+ if( credential == null )
+ {
+ // Subject credential must also be null
+ isValid = subjectCredential == null;
+ }
+ if( isValid == true )
+ return true;
+
+ if( subjectCredential.getClass().isAssignableFrom(credential.getClass()) ==
false )
+ return false;
+
+ if( subjectCredential instanceof Comparable )
+ {
+ Comparable c = (Comparable) subjectCredential;
+ isValid = c.compareTo(credential) == 0;
+ }
+ else if( subjectCredential instanceof char[] )
+ {
+ char[] a1 = (char[]) subjectCredential;
+ char[] a2 = (char[]) credential;
+ isValid = Arrays.equals(a1, a2);
+ }
+ else if( subjectCredential instanceof byte[] )
+ {
+ byte[] a1 = (byte[]) subjectCredential;
+ byte[] a2 = (byte[]) credential;
+ isValid = Arrays.equals(a1, a2);
+ }
+ else
+ {
+ isValid = subjectCredential.equals(credential);
+ }
+
+ if( isValid )
+ {
+ activeSubject.set(info.subject);
+ }
+
+ return isValid;
+ }
+
+ private void updateCache(Subject subject, Principal principal, Object
credential)
+ {
+ DomainInfo info = new DomainInfo();
+ info.subject = subject;
+ info.credential = credential;
+
+ /* If we don't have a cache policy create a default timed cache
+ that has an 1800 sec lifetime, is thread-safe, and a resolution
+ of 60 seconds.
+ */
+ if( domainCache == null )
+ {
+ domainCache = new TimedCachePolicy(1800, true, 60);
+ try
+ {
+ domainCache.init();
+ domainCache.start();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /* Get the Subject callerPrincipal by looking for a Group called
+ 'CallerPrincipal' and roles by looking for a Group called 'Roles'
+ */
+ Set subjectGroups = subject.getPrincipals(Group.class);
+ Iterator iter = subjectGroups.iterator();
+ while( iter.hasNext() )
+ {
+ Group grp = (Group) iter.next();
+ String name = grp.getName();
+ if( name.equals("CallerPrincipal") )
+ {
+ Enumeration members = grp.members();
+ if( members.hasMoreElements() )
+ info.callerPrincipal = (Principal) members.nextElement();
+ }
+ else if( name.equals("Roles") )
+ info.roles = grp;
+ }
+
+ /* Handle null principals with no callerPrincipal. This is an indication
+ of an user that has not provided any authentication info, but
+ has been authenticated by the domain login module stack. Here we look
+ for the first non-Group Principal and use that.
+ */
+ if( principal == null && info.callerPrincipal == null )
+ {
+ Set subjectPrincipals = subject.getPrincipals(Principal.class);
+ iter = subjectPrincipals.iterator();
+ while( iter.hasNext() )
+ {
+ Principal p = (Principal) iter.next();
+ if( (p instanceof Group) == false )
+ info.callerPrincipal = p;
+ }
+ }
+
+ /* If the user already exists another login is active. Currently
+ only one is allowed so remove the old and insert the new.
+ */
+ if( domainCache.peek(principal) != null )
+ domainCache.remove(principal);
+ domainCache.insert(principal, info);
+ }
+
+}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development