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

Reply via email to