User: luke_t
Date: 02/02/03 13:18:19
Modified: src/main/org/jboss/security/plugins JaasSecurityManager.java
Log:
code formatting
Revision Changes Path
1.18 +512 -498
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.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- JaasSecurityManager.java 2001/12/18 21:35:35 1.17
+++ JaasSecurityManager.java 2002/02/03 21:18:19 1.18
@@ -1,498 +1,512 @@
-/*
- * JBoss, the OpenSource EJB server
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.security.plugins;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import java.security.Principal;
-import java.security.acl.Group;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.callback.CallbackHandler;
-
-import org.jboss.logging.Logger;
-import org.jboss.security.AppPolicy;
-import org.jboss.security.RealmMapping;
-import org.jboss.security.SecurityPolicy;
-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.17 $
-*/
-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 log4j category for the security manager domain
- */
- private Logger log;
- /** 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;
- this.log = Logger.getLogger(getClass().getName()+"."+securityDomain);
- }
-
- /** 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;
- }
-
- /** Return the set of domain roles the principal has been assigned.
- @return The Set<Principal> for the application domain roles that the
- principal has been assigned.
- */
- public Set getUserRoles(Principal principal)
- {
- HashSet userRoles = null;
- 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 )
- {
- userRoles = new HashSet();
- Enumeration members = roles.members();
- while( members.hasMoreElements() )
- {
- Principal role = (Principal) members.nextElement();
- userRoles.add(role);
- }
- }
- }
- return userRoles;
- }
-
- /** 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)
- {
- // Don't log anonymous user failures
- if( principal != null && principal.getName() != null ||
log.isTraceEnabled() )
- log.debug("Login failure", e);
- }
-
- 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;
- }
- // See if the credential is assignable to the cache value
- else if( subjectCredential.getClass().isAssignableFrom(credential.getClass())
== false )
- isValid = false;
- else
- {
- /* Validate the credential by trying Comparable, char[], byte[],
- and finally Object.equals()
- */
- 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 the credentials match set the thread's active Subject
- 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.create();
- domainCache.start();
- }
- catch(Exception e)
- {
- log.info("Failed to initialize TimedCachePolicy", e);
- }
- }
-
- /* 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, the OpenSource EJB server
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.security.plugins;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.callback.CallbackHandler;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.AppPolicy;
+import org.jboss.security.RealmMapping;
+import org.jboss.security.SecurityPolicy;
+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.18 $
+ */
+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 log4j category for the security manager domain */
+ private Logger log;
+
+ /**
+ * 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;
+ this.log = Logger.getLogger(getClass().getName() + "." + securityDomain);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Return the set of domain roles the principal has been assigned.
+ * @return The Set<Principal> for the application domain roles that the
+ * principal has been assigned.
+ */
+ public Set getUserRoles(Principal principal)
+ {
+ HashSet userRoles = null;
+ 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)
+ {
+ userRoles = new HashSet();
+ Enumeration members = roles.members();
+ while(members.hasMoreElements())
+ {
+ Principal role = (Principal)members.nextElement();
+ userRoles.add(role);
+ }
+ }
+ }
+ return userRoles;
+ }
+
+ /**
+ * 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)
+ {
+ // Don't log anonymous user failures
+ if(principal != null && principal.getName() != null ||
log.isTraceEnabled())
+ log.debug("Login failure", e);
+ }
+
+ 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 anonymous user
+ if(credential == null)
+ {
+ // Subject credential must also be null
+ isValid = subjectCredential == null;
+ }
+ // See if the credential is assignable to the cache value
+ else if(subjectCredential.getClass().isAssignableFrom(credential.getClass())
== false)
+ isValid = false;
+ else
+ {
+ /* Validate the credential by trying Comparable, char[], byte[],
+ and finally Object.equals()
+ */
+ 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 the credentials match set the thread's active Subject
+ 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.create();
+ domainCache.start();
+ }
+ catch(Exception e)
+ {
+ log.info("Failed to initialize TimedCachePolicy", e);
+ }
+ }
+
+ /* 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]
https://lists.sourceforge.net/lists/listinfo/jboss-development