Hitachi

uCosminexus Application Server Security Management Guide


5.12.3 Examples of implementing custom login modules

The following are examples of implementing custom login modules and the Principal object.

The first example of implementing a custom login module does not use the session failover functionality. The example of using the session failover functionality includes the portion that is different from the example of not using the session failover functionality.

Organization of this subsection

(1) Example of implementation not using the session failover functionality

The following is an example of implementing a custom login module without the session failover functionality.

/**
* The LoginModule implementation class is created by inheriting the LoginModule interface.
*
*/
public class ExampleLoginModule implements LoginModule
{
    // The following are used to reference the parameter values passed to the initialize() method.
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map sharedState;
    private Map options;
 
    // The following define the name used to obtain the user ID and password values from sharedState.
    // "simple.login.username" and "simple.login.password" can be specified in
    // the integrated user management configuration file.
    private static final String USERNAME = "simple.login.username";
    private static final String PASSWORD = "simple.login.password";
    // The following stores the user ID used for authentication. The value is set by login() and referenced by commit().
    private String username;
 
    // The following stores success or failure of login(). "True" means login() succeeded while "false" means login() failed.
    // The value is set by login() and referenced by commit().
    private boolean succeeded;
 
    // The following stores success or failure of commit(). True means commit() succeeded while false means commit() failed.
    // The value is set by commit() and referenced by abort().
    private boolean commitSucceeded;
 
    /**
    * The initialize() method stores the parameters passed to the arguments in the member variables.
    * It also performs initialization when needed.
    * (It is called once when this class is instantiated.)
    *
    */
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
    {
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.sharedState = sharedState;
        this.options = options;
    }
 
    /**
    * The login() method obtains the user ID needed for authentication and performs authentication.
    * In this example, "succeeded" is set to true when authentication succeeds. The authenticated user ID is 
    * stored in "username".
    *
    */
    public boolean login()
        throws LoginException
    {
        // To support single sign-on, the user ID and password are obtained to be stored in sharedState.
        this.username = (String)this.sharedState.get(USERNAME);
        String password = (String)this.sharedState.get(PASSWORD);
 
        // When no user ID is in sharedState, CallbackHandler is used to obtain
        // the user ID and password. (This example assumes that WebPasswordHandler assign the values to
        // WebPasswordCallback.)
        if (this.username == null || this.username.length() == 0) {
            WebPasswordCallback webpc = new WebPasswordCallback();
            webpc.setOption(WebPasswordCallback.GETPW);
            Callback callbacks[] = new Callback[] { webpc };
            try {
                this.callbackHandler.handle(callbacks);
            }
            catch (Exception ex) {
                // Exception handling is performed.
            }
            // The user ID and password are obtained from Callback.
            this.username = webpc.getName();
            password = webpc.getPassword();
        }
        // The following checks if the user ID used for authentication is present. If no user ID is present, exception is returned.
        if (this.username == null || this.username.length() == 0) {
            throw new FailedLoginException();
        }
 
        // The application authentication process is performed.
        // When authentication is successful, "succeeded" is set to "true".
 
        /* Enter the authentication process here. */
 
        if (!succeeded) {
            throw new FailedLoginException();
        }
        return succeeded;
    }
    /**
    * The commit () method associates the Principal object to the Subject to indicate that authentication is completed.
    * (SimplePrincipal is a class which is created by inheriting the Principal and Serializable interfaces.)
    *
    */
    public boolean commit()
        throws LoginException
    {
        // The following associates the Principal object to the Subject to allow join the login session managed by integrated user management
        // and support of the single sign-on function.
        this.subject.getPrincipals().add( new SimplePrincipal(this.username) );
 
        /* Enter the process which associates the user attributes to the Subject. */
 
        return this.commitSucceeded = true;
    }
    /**
    * The abort() method is invoked when the login() or commit() method 
    * failed.
    *
    */
    public boolean abort()
        throws LoginException
    {
        if (this.commitSucceeded) {
            // This releases the Principal and user attributes associated to the Subject.
            // In this example, the logout() method is invoked.
            logout();
        }
        return true;
    }
    /**
    * The logout () method is invoked to log out.
    * This method is used to release the Principal and user attributes associated to the Subject.
    *
    *
    */
    public boolean logout()
        throws LoginException
    {
        // Enter the process which deletes the Principal and user attributes from the Subject.
        // Add the process which releases the resources secured by the login() method.
        return true;
    }
}

(2) Example of Implementation using the session failover functionality

The login and commitment methods are the same as the example not using the session failover functionality. The following shows the difference in the logout method implementation.

/**
 * The LoginModule implementation class is created by inheriting the LoginModule interface.
 */
public class ExampleLoginModule implements LoginModule
{
  /**
   * The logout () method is invoked to log out.
   * This method is used to release the resources secured at the time of login.
   */
  public boolean logout() throws LoginException
  {
    if (callbackHandler != null) {
        WebLogoutCallback callback = new WebLogoutCallback();
        try {
            callbackHandler.handle(new Callback[]{callback});
        } catch (Exception e) { ... }
        String uid = callback.getUserID();
        HttpSession session = callback.getSession();
        // Add the process which releases the resources secured by the login() method.
        // to delete the information registered in the global session, etc.
    }
    return true;
  }
}

The logout method release the resources secured at the time of login. Note that the session failover functionality does not fail over the Subject and Principal.

(3) Example of implementing the Principal object

Create the Principal object by inheriting the java.security.Principal and java.io.Serializable interfaces. The following is an example of implementing the Principal object.

import java.security.Principal;
import java.io.Serializable;
 
/**
* The Principal implementation class is created by inheriting the Principal and Serializable interfaces.
*
*/
public class SimplePrincipal implements Principal, Serializable
{
  private String name;
 
  public SimplePrincipal(String name) {
    if (name == null) throw new NullPointerException();
    this.name = name;
  }
  public String getName() { return name; }
  public String toString() { return getName(); }
  public boolean equals(Object o) {
    if (o == null) return false;
    if (this == o) return true;
    if (!(o instanceof SimplePrincipal)) return false;
    SimplePrincipal rhs = (SimplePrincipal)o;
    if (getName().equals(rhs.getName())) return true;
    return false;
  }
  public int hashCode() { return getName().hashCode(); }
}