Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt in the distribution for a
  * full listing of individual contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
 package org.jboss.security.auth.spi;
 
 
 import java.util.Map;
 import java.util.Set;
 
 
This class implements the common functionality required for a JAAS server side LoginModule and implements the JBossSX standard Subject usage pattern of storing identities and roles. Subclass this module to create your own custom LoginModule and override the login(), getRoleSets() and getIdentity() methods.

You may also wish to override

    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
 
In which case the first line of your initialize() method should be:
    super.initialize(subject, callbackHandler, sharedState, options);
 

You may also wish to override

    public boolean login() throws LoginException
 
In which case the last line of your login() method should be
    return super.login();
 

Author(s):
Edward Kenworthy, 12th Dec 2000
Scott.Stark@jboss.org
Version:
$Revision: 73520 $
 
 public abstract class AbstractServerLoginModule implements LoginModule
 {
    protected Subject subject;
    protected CallbackHandler callbackHandler;
    @SuppressWarnings("unchecked")
    protected Map sharedState;
    @SuppressWarnings("unchecked")
    protected Map options;
    protected Logger log;
   
Flag indicating if the shared credential should be used
 
    protected boolean useFirstPass;
   
Flag indicating if the login phase succeeded. Subclasses that override the login method must set this to true on successful completion of login
 
    protected boolean loginOk;
   
An optional custom Principal class implementation
 
    protected String principalClassName;
   
the principal to use when a null username and password are seen
 
 
 //--- Begin LoginModule interface methods
    
Initialize the login module. This stores the subject, callbackHandler and sharedState and options for the login session. Subclasses should override if they need to process their own options. A call to super.initialize(...) must be made in the case of an override.

Parameters:
subject the Subject to update after a successful login.
callbackHandler the CallbackHandler that will be used to obtain the the user identity and credentials.
sharedState a Map shared between all configured login module instances
options the parameters passed to the login module.
Option:
password-stacking: If this is set to "useFirstPass", the login identity will be taken from the javax.security.auth.login.name value of the sharedState map, and the proof of identity from the javax.security.auth.login.password value of the sharedState map.
Option:
principalClass: A Principal implementation that support a ctor taking a String argument for the princpal name.
Option:
unauthenticatedIdentity: the name of the principal to asssign and authenticate when a null username and password are seen.
   public void initialize(Subject subjectCallbackHandler callbackHandler,
      Map<String,?> sharedStateMap<String,?> options)
   {
      this. = subject;
      this. = callbackHandler;
      this. = sharedState;
      this. = options;
       = Logger.getLogger(getClass());
      .trace("initialize");
      //log securityDomain, if set.
      .trace("Security domain: " + 
      /* Check for password sharing options. Any non-null value for
         password_stacking sets useFirstPass as this module has no way to
         validate any shared password.
      */
      String passwordStacking = (Stringoptions.get("password-stacking");
      ifpasswordStacking != null && passwordStacking.equalsIgnoreCase("useFirstPass") )
          = true;
      // Check for a custom Principal implementation
       = (Stringoptions.get("principalClass");
      // Check for unauthenticatedIdentity option.
      String name = (Stringoptions.get("unauthenticatedIdentity");
      ifname != null )
      {
         try
         {
             = createIdentity(name);
            .trace("Saw unauthenticatedIdentity="+name);
         }
         catch(Exception e)
         {
            .warn("Failed to create custom unauthenticatedIdentity"e);
         }
      }
   }

   
Looks for javax.security.auth.login.name and javax.security.auth.login.password values in the sharedState map if the useFirstPass option was true and returns true if they exist. If they do not or are null this method returns false. Note that subclasses that override the login method must set the loginOk ivar to true if the login succeeds in order for the commit phase to populate the Subject. This implementation sets loginOk to true if the login() method returns true, otherwise, it sets loginOk to false.
   public boolean login() throws LoginException
   {
      .trace("login");
       = false;
      // If useFirstPass is true, look for the shared password
      if == true )
      {
         try
         {
            Object identity = .get("javax.security.auth.login.name");
            Object credential = .get("javax.security.auth.login.password");
            ifidentity != null && credential != null )
            {
                = true;
               return true;
            }
            // Else, fall through and perform the login
         }
         catch(Exception e)
         {   // Dump the exception and continue
            .error("login failed"e);
         }
      }
      return false;
   }

   
Method to commit the authentication process (phase 2). If the login method completed successfully as indicated by loginOk == true, this method adds the getIdentity() value to the subject getPrincipals() Set. It also adds the members of each Group returned by getRoleSets() to the subject getPrincipals() Set.

Returns:
true always.
See also:
javax.security.auth.Subject;
java.security.acl.Group;
   public boolean commit() throws LoginException
   {
      .trace("commit, loginOk="+);
      if == false )
         return false;
      Set<Principalprincipals = .getPrincipals();
      Principal identity = getIdentity();
      principals.add(identity);
      Group[] roleSets = getRoleSets();
      for(int g = 0; g < roleSets.lengthg ++)
      {
         Group group = roleSets[g];
         String name = group.getName();
         Group subjectGroup = createGroup(nameprincipals);
         ifsubjectGroup instanceof NestableGroup )
         {
            /* A NestableGroup only allows Groups to be added to it so we
            need to add a SimpleGroup to subjectRoles to contain the roles
            */
            SimpleGroup tmp = new SimpleGroup("Roles");
            subjectGroup.addMember(tmp);
            subjectGroup = tmp;
         }
         // Copy the group members to the Subject group
         Enumeration<? extends Principalmembers = group.members();
         whilemembers.hasMoreElements() )
         {
            Principal role = (Principalmembers.nextElement();
            subjectGroup.addMember(role);
         }
      }
      return true;
   }

   
Method to abort the authentication process (phase 2).

Returns:
true alaways
   public boolean abort() throws LoginException
   {
      .trace("abort");
      return true;
   }
   
   
Remove the user identity and roles added to the Subject during commit.

Returns:
true always.
   public boolean logout() throws LoginException
   {
      .trace("logout");
      // Remove the user identity
      Principal identity = getIdentity();
      Set<Principalprincipals = .getPrincipals();
      principals.remove(identity);
      // Remove any added Groups...
      return true;
   }
   //--- End LoginModule interface methods
   
   // --- Protected methods
   
   
Overriden by subclasses to return the Principal that corresponds to the user primary identity.
   abstract protected Principal getIdentity();
   
Overriden by subclasses to return the Groups that correspond to the to the role sets assigned to the user. Subclasses should create at least a Group named "Roles" that contains the roles assigned to the user. A second common group is "CallerPrincipal" that provides the application identity of the user rather than the security domain identity.

Returns:
Group[] containing the sets of roles
   abstract protected Group[] getRoleSets() throws LoginException;
   
   protected boolean getUseFirstPass()
   {
      return ;
   }
   {
      return ;
   }

   
Find or create a Group with the given name. Subclasses should use this method to locate the 'Roles' group or create additional types of groups.

Returns:
A named Group from the principals set.
   protected Group createGroup(String nameSet<Principalprincipals)
   {
      Group roles = null;
      Iterator<Principaliter = principals.iterator();
      whileiter.hasNext() )
      {
         Object next = iter.next();
         if( (next instanceof Group) == false )
            continue;
         Group grp = (Groupnext;
         ifgrp.getName().equals(name) )
         {
            roles = grp;
            break;
         }
      }
      // If we did not find a group create one
      ifroles == null )
      {
         roles = new SimpleGroup(name);
         principals.add(roles);
      }
      return roles;
   }

   
Utility method to create a Principal for the given username. This creates an instance of the principalClassName type if this option was specified using the class constructor matching: ctor(String). If principalClassName was not specified, a SimplePrincipal is created.

Parameters:
username the name of the principal
Returns:
the principal instance
Throws:
java.lang.Exception thrown if the custom principal type cannot be created.
 
   @SuppressWarnings("unchecked")
   protected Principal createIdentity(String username)
      throws Exception
   {
      Principal p = null;
      if == null )
      {
         p = new SimplePrincipal(username);
      }
      else
      {
            ClassLoader loader = SecurityActions.getContextClassLoader();
            Class clazz = loader.loadClass();
            Class[] ctorSig = {String.class};
            Constructor ctor = clazz.getConstructor(ctorSig);
            Object[] ctorArgs = {username};
            p = (Principalctor.newInstance(ctorArgs);
      }
      return p;
   }
New to GrepCode? Check out our FAQ X