FileDocCategorySizeDatePackage
JAASMemoryLoginModule.javaAPI DocGlassfish v2 API15741Fri May 04 22:32:16 BST 2007org.apache.catalina.realm

JAASMemoryLoginModule

public class JAASMemoryLoginModule extends MemoryRealm implements LoginModule, org.apache.catalina.Realm

Implementation of the JAAS LoginModule interface, primarily for use in testing JAASRealm. It utilizes an XML-format data file of username/password/role information identical to that supported by org.apache.catalina.realm.MemoryRealm (except that digested passwords are not supported).

This class recognizes the following string-valued options, which are specified in the configuration file (and passed to our constructor in the options argument:

  • debug - Set to "true" to get debugging messages generated to System.out. The default value is false.
  • pathname - Relative (to the pathname specified by the "catalina.base" system property) or absolute pahtname to the XML file containing our user information, in the format supported by {@link MemoryRealm}. The default value matches the MemoryRealm default.

IMPLEMENTATION NOTE - This class implements Realm only to satisfy the calling requirements of the GenericPrincipal constructor. It does not actually perform the functionality required of a Realm implementation.

author
Craig R. McClanahan
version
$Revision: 1.6 $ $Date: 2007/05/05 05:32:16 $

Fields Summary
private static com.sun.org.apache.commons.logging.Log
log
protected CallbackHandler
callbackHandler
The callback handler responsible for answering our requests.
protected boolean
committed
Has our own commit() returned successfully?
protected boolean
debug
Should we log debugging messages?
protected Map
options
The configuration information for this LoginModule.
protected String
pathname
The absolute or relative pathname to the XML configuration file.
protected Principal
principal
The Principal identified by our validation, or null if validation falied.
protected HashMap
principals
The set of Principals loaded from our configuration file.
protected static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
protected Map
sharedState
The state information that is shared with other configured LoginModule instances.
protected Subject
subject
The subject for which we are performing authentication.
Constructors Summary
public JAASMemoryLoginModule()



    // --------------------------------------------------------- Public Methods

      
        log.debug("MEMORY LOGIN MODULE");
    
Methods Summary
public booleanabort()
Phase 2 of authenticating a Subject when Phase 1 fails. This method is called if the LoginContext failed somewhere in the overall authentication chain.

return
true if this method succeeded, or false if this LoginModule should be ignored
exception
LoginException if the abort fails


        // If our authentication was not successful, just return false
        if (principal == null)
            return (false);

        // Clean up if overall authentication failed
        if (committed)
            logout();
        else {
            committed = false;
            principal = null;
        }
        log.debug("Abort");
        return (true);

    
public booleancommit()
Phase 2 of authenticating a Subject when Phase 1 was successful. This method is called if the LoginContext succeeded in the overall authentication chain.

return
true if the authentication succeeded, or false if this LoginModule should be ignored
exception
LoginException if the commit fails

        log.debug("commit " + principal);

        // If authentication was not successful, just return false
        if (principal == null)
            return (false);

        // Add our Principal to the Subject if needed
        if (!subject.getPrincipals().contains(principal))
            subject.getPrincipals().add(principal);

        committed = true;
        return (true);

    
public org.apache.catalina.deploy.SecurityConstraint[]findSecurityConstraints(org.apache.catalina.HttpRequest request, org.apache.catalina.Context context)
Return the SecurityConstraints configured to guard the request URI for this request, or null if there is no such constraint.

param
request Request we are processing
param
context Context the Request is mapped to

        ArrayList results = null;
        // Are there any defined security constraints?
        SecurityConstraint constraints[] = context.findConstraints();
        if ((constraints == null) || (constraints.length == 0)) {
            if (debug)
                log("  No applicable constraints defined");
            return (null);
        }

        // Check each defined security constraint
        HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
        String uri = request.getDecodedRequestURI();
        String contextPath = hreq.getContextPath();
        if (contextPath.length() > 0)
            uri = uri.substring(contextPath.length());
        uri = RequestUtil.URLDecode(uri); // Before checking constraints
        String method = hreq.getMethod();
        for (int i = 0; i < constraints.length; i++) {
            /* SJSWS 6324431
            if (debug)
                log("  Checking constraint '" + constraints[i] +
                    "' against " + method + " " + uri + " --> " +
                    constraints[i].included(uri, method));
            */
            // START SJSWS 6324431
            boolean caseSensitiveMapping = 
                ((StandardContext)context).isCaseSensitiveMapping();
            if (debug)
                log("  Checking constraint '" + constraints[i] +
                    "' against " + method + " " + uri + " --> " +
                    constraints[i].included(uri, method, 
                                            caseSensitiveMapping));
            // END SJSWS 6324431
            /* SJSWS 6324431
            if (constraints[i].included(uri, method)) {
            */
            // START SJSWS 6324431
            if (constraints[i].included(uri, method, 
                                        caseSensitiveMapping)) {
            // END SJSWS 6324431
                if(results == null) {
                    results = new ArrayList();
                }
                results.add(constraints[i]);
            }
        }

        // No applicable security constraint was found
        if (debug)
            log("  No applicable constraint located");
        if(results == null)
            return null;
        SecurityConstraint [] array = new SecurityConstraint[results.size()];
        System.arraycopy(results.toArray(), 0, array, 0, array.length);
        return array;
    
public voidinitialize(javax.security.auth.Subject subject, javax.security.auth.callback.CallbackHandler callbackHandler, java.util.Map sharedState, java.util.Map options)
Initialize this LoginModule with the specified configuration information.

param
subject The Subject to be authenticated
param
callbackHandler A CallbackHandler for communicating with the end user as necessary
param
sharedState State information shared with other LoginModule instances
param
options Configuration information for this specific LoginModule instance

        log.debug("Init");

        // Save configuration values
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.sharedState = sharedState;
        this.options = options;

        // Perform instance-specific initialization
        this.debug = "true".equalsIgnoreCase((String) options.get("debug"));
        if (options.get("pathname") != null)
            this.pathname = (String) options.get("pathname");

        // Load our defined Principals
        load();

    
protected voidload()
Load the contents of our configuration file.


        // Validate the existence of our configuration file
        File file = new File(pathname);
        if (!file.isAbsolute())
            file = new File(System.getProperty("catalina.base"), pathname);
        if (!file.exists() || !file.canRead()) {
            log("Cannot load configuration file " + file.getAbsolutePath());
            return;
        }

        // Load the contents of our configuration file
        Digester digester = new Digester();
        digester.setValidating(false);
        digester.addRuleSet(new MemoryRuleSet());
        try {
            digester.push(this);
            digester.parse(file);
        } catch (Exception e) {
            log("Error processing configuration file " +
                file.getAbsolutePath(), e);
            return;
        }

    
public booleanlogin()
Phase 1 of authenticating a Subject.

return
true if the authentication succeeded, or false if this LoginModule should be ignored
exception
LoginException if the authentication fails


        // Set up our CallbackHandler requests
        if (callbackHandler == null)
            throw new LoginException("No CallbackHandler specified");
        Callback callbacks[] = new Callback[2];
        callbacks[0] = new NameCallback("Username: ");
        callbacks[1] = new PasswordCallback("Password: ", false);

        // Interact with the user to retrieve the username and password
        String username = null;
        String password = null;
        try {
            callbackHandler.handle(callbacks);
            username = ((NameCallback) callbacks[0]).getName();
            password =
                new String(((PasswordCallback) callbacks[1]).getPassword());
        } catch (IOException e) {
            throw new LoginException(e.toString());
        } catch (UnsupportedCallbackException e) {
            throw new LoginException(e.toString());
        }

        // Validate the username and password we have received
        principal = super.authenticate(username, password);

        log.debug("login " + username + " " + principal);

        // Report results based on success or failure
        if (principal != null) {
            return (true);
        } else {
            throw new
                FailedLoginException("Username or password is incorrect");
        }

    
public booleanlogout()
Log out this user.

return
true in all cases because thie LoginModule should not be ignored
exception
LoginException if logging out failed


        subject.getPrincipals().remove(principal);
        committed = false;
        principal = null;
        return (true);