Lots more authentication code cleaning
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Sat, 16 Jun 2007 12:58:30 +0000 (12:58 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Sat, 16 Jun 2007 12:58:30 +0000 (12:58 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2245 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationEngine.java
src/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationHandler.java
src/edu/internet2/middleware/shibboleth/idp/authn/LoginContext.java
src/edu/internet2/middleware/shibboleth/idp/authn/impl/IPAddressHandler.java
src/edu/internet2/middleware/shibboleth/idp/authn/impl/RemoteUserAuthenticationHandler.java
src/edu/internet2/middleware/shibboleth/idp/authn/impl/UsernamePasswordAuthenticationHandler.java
src/edu/internet2/middleware/shibboleth/idp/authn/impl/UsernamePasswordAuthenticationServlet.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSOProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/SSOProfileHandler.java

index 4316219..0b27f33 100644 (file)
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpSession;
 
 import org.apache.log4j.Logger;
 import org.joda.time.DateTime;
+import org.opensaml.xml.util.DatatypeHelper;
 import org.opensaml.xml.util.Pair;
 
 import edu.internet2.middleware.shibboleth.common.profile.ProfileHandlerManager;
@@ -46,7 +47,7 @@ import edu.internet2.middleware.shibboleth.idp.session.impl.ServiceInformationIm
 public class AuthenticationEngine extends HttpServlet {
 
     /** Class logger. */
-    private static final Logger log = Logger.getLogger(AuthenticationEngine.class);
+    private static final Logger LOG = Logger.getLogger(AuthenticationEngine.class);
 
     /**
      * Gets the manager used to retrieve handlers for requests.
@@ -75,94 +76,234 @@ public class AuthenticationEngine extends HttpServlet {
     public AuthenticationHandlerManager getAuthenticationHandlerManager() {
         return (AuthenticationHandlerManager) getServletContext().getAttribute("authenticationHandlerManager");
     }
-    
 
     /**
      * Returns control back to the authentication engine.
      * 
      * @param httpRequest current http request
      * @param httpResponse current http response
-     * @param loginContext user login context
      */
     public static void returnToAuthenticationEngine(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Returning control to authentication engine");
+        }
         HttpSession httpSession = httpRequest.getSession();
-
         LoginContext loginContext = (LoginContext) httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
-        
+        forwardRequest(loginContext.getAuthenticationEngineURL(), httpRequest, httpResponse);
+    }
+
+    /**
+     * Returns control back to the profile handler that invoked the authentication engine.
+     * 
+     * @param loginContext current login context
+     * @param httpRequest current http request
+     * @param httpResponse current http response
+     */
+    public static void returnToProfileHandler(LoginContext loginContext, HttpServletRequest httpRequest,
+            HttpServletResponse httpResponse) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Returning control to profile handler at: " + loginContext.getProfileHandlerURL());
+        }
+        forwardRequest(loginContext.getProfileHandlerURL(), httpRequest, httpResponse);
+    }
+
+    /**
+     * Forwards a request to the given path.
+     * 
+     * @param forwardPath path to forward the request to
+     * @param httpRequest current HTTP request
+     * @param httpResponse current HTTP response
+     */
+    protected static void forwardRequest(String forwardPath, HttpServletRequest httpRequest,
+            HttpServletResponse httpResponse) {
         try {
-            RequestDispatcher distpather = httpRequest.getRequestDispatcher(loginContext.getAuthenticationManagerURL());
-            distpather.forward(httpRequest, httpResponse);
+            RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(forwardPath);
+            dispatcher.forward(httpRequest, httpResponse);
         } catch (IOException e) {
-            log.fatal("Unable to return control back to authentication engine", e);
+            LOG.fatal("Unable to return control back to authentication engine", e);
         } catch (ServletException e) {
-            log.fatal("Unable to return control back to authentication engine", e);
+            LOG.fatal("Unable to return control back to authentication engine", e);
         }
     }
 
     /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
     protected void service(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws ServletException,
             IOException {
-        HttpSession httpSession = httpRequest.getSession();
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Processing incoming request");
+        }
 
+        HttpSession httpSession = httpRequest.getSession();
         LoginContext loginContext = (LoginContext) httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
         if (loginContext == null) {
-            // TODO error
+            LOG.error("Incoming request does not have attached login context");
+            throw new ServletException("Incoming request does not have attached login context");
         }
 
-        // If authentication has been attempted, don't try it again.
-        if (loginContext.getAuthenticationAttempted()) {
-            handleNewAuthnRequest(loginContext, httpRequest, httpResponse);
+        if (!loginContext.getAuthenticationAttempted()) {
+            String shibSessionId = (String) httpSession.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
+            Session shibSession = getSessionManager().getSession(shibSessionId);
+
+            if (shibSession != null) {
+                AuthenticationMethodInformation authenticationMethod = getUsableExistingAuthenticationMethod(
+                        loginContext, shibSession);
+                if (authenticationMethod != null) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("An active authentication method is applicable for relying party.  "
+                                + "Using authentication method " + authenticationMethod.getAuthenticationMethod()
+                                + " as authentication method to relying party without re-authenticating user.");
+                    }
+                    authenticateUserWithActiveMethod(httpRequest, httpResponse, authenticationMethod);
+                }
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("No active authentication method is applicable for relying party.  "
+                        + "Authenticating user with to be determined method.");
+            }
+            authenticateUserWithoutActiveMethod1(httpRequest, httpResponse);
         } else {
-            finishAuthnRequest(loginContext, httpRequest, httpResponse);
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Request returned from authentication handler, completing authentication process.");
+            }
+            authenticateUserWithoutActiveMethod2(httpRequest, httpResponse);
         }
     }
 
     /**
-     * Handle a new authentication request.
+     * Completes the authentication request using an existing, active, authentication method for the current user.
      * 
-     * @param loginContext The {@link LoginContext} for the new authentication request
-     * @param httpRequest The servlet request containing the authn request
-     * @param httpResponse The associated servlet response.
+     * @param httpRequest current HTTP request
+     * @param httpResponse current HTTP response
+     * @param authenticationMethod authentication method to use to complete the request
+     */
+    protected void authenticateUserWithActiveMethod(HttpServletRequest httpRequest, HttpServletResponse httpResponse,
+            AuthenticationMethodInformation authenticationMethod) {
+        HttpSession httpSession = httpRequest.getSession();
+
+        String shibSessionId = (String) httpSession.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
+        Session shibSession = getSessionManager().getSession(shibSessionId);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Populating login context with existing session and authentication method information.");
+        }
+        LoginContext loginContext = (LoginContext) httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
+        loginContext.setAuthenticationDuration(authenticationMethod.getAuthenticationDuration());
+        loginContext.setAuthenticationInstant(authenticationMethod.getAuthenticationInstant());
+        loginContext.setAuthenticationMethod(authenticationMethod.getAuthenticationMethod());
+        loginContext.setPrincipalAuthenticated(true);
+        loginContext.setPrincipalName(shibSession.getPrincipalName());
+
+        ServiceInformation serviceInfo = new ServiceInformationImpl(loginContext.getRelyingPartyId(), new DateTime(),
+                authenticationMethod);
+        shibSession.getServicesInformation().put(serviceInfo.getEntityID(), serviceInfo);
+
+        returnToProfileHandler(loginContext, httpRequest, httpResponse);
+    }
+
+    /**
+     * Performs the first part of user authentication. An authentication handler is determined, the login context is
+     * populated with some initial information, and control is forward to the selected handler so that it may
+     * authenticate the user.
      * 
-     * @throws IOException thrown if there is a problem reading/writting to the HTTP request/response
-     * @throws ServletException thrown if there is a problem transferring control to the authentication handler
+     * @param httpRequest current HTTP request
+     * @param httpResponse current HTTP response
      */
-    protected void handleNewAuthnRequest(LoginContext loginContext, HttpServletRequest httpRequest,
-            HttpServletResponse httpResponse) throws ServletException, IOException {
+    protected void authenticateUserWithoutActiveMethod1(HttpServletRequest httpRequest, 
+            HttpServletResponse httpResponse) {
+        HttpSession httpSession = httpRequest.getSession();
+        LoginContext loginContext = (LoginContext) httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
 
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Selecting appropriate authentication method for request.");
+        }
+        Pair<String, AuthenticationHandler> handler = getAuthenticationHandlerManager().getAuthenticationHandler(
+                loginContext);
+
+        if (handler == null) {
+            loginContext.setPrincipalAuthenticated(false);
+            loginContext.setAuthenticationFailureMessage("No AuthenticationHandler satisfys the request from: "
+                            + loginContext.getRelyingPartyId());
+            LOG.error("No AuthenticationHandler satisfys the request from relying party: "
+                    + loginContext.getRelyingPartyId());
+            returnToProfileHandler(loginContext, httpRequest, httpResponse);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Authentication method " + handler.getFirst() + " will be used to authenticate user.");
+        }
+        loginContext.setAuthenticationAttempted();
+        loginContext.setAuthenticationDuration(handler.getSecond().getAuthenticationDuration());
+        loginContext.setAuthenticationMethod(handler.getFirst());
+        loginContext.setAuthenticationEngineURL(httpRequest.getRequestURI());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Transferring control to authentication handler of type: "
+                    + handler.getSecond().getClass().getName());
+        }
+        handler.getSecond().login(httpRequest, httpResponse);
+    }
+
+    /**
+     * Performs the second part of user authentication. The principal name set by the authentication handler is
+     * retrieved and pushed in to the login context, a Shibboleth session is created if needed, information indicating
+     * that the user has logged into the service is recorded and finally control is returned back to the profile
+     * handler.
+     * 
+     * @param httpRequest current HTTP request
+     * @param httpResponse current HTTP response
+     */
+    protected void authenticateUserWithoutActiveMethod2(HttpServletRequest httpRequest, 
+            HttpServletResponse httpResponse) {
         HttpSession httpSession = httpRequest.getSession();
+
+        String principalName = (String) httpRequest.getAttribute(AuthenticationHandler.PRINCIPAL_NAME_KEY);
+        LoginContext loginContext = (LoginContext) httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
+        if (DatatypeHelper.isEmpty(principalName)) {
+            loginContext.setPrincipalAuthenticated(false);
+            loginContext.setAuthenticationFailureMessage("No principal name returned from authentication handler.");
+            LOG.error("No principal name returned from authentication method: "
+                    + loginContext.getAuthenticationMethod());
+            returnToProfileHandler(loginContext, httpRequest, httpResponse);
+        }
+        loginContext.setPrincipalName(principalName);
+
         String shibSessionId = (String) httpSession.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
         Session shibSession = getSessionManager().getSession(shibSessionId);
 
-        AuthenticationMethodInformation authenticationMethod = getUsableExistingAuthenticationMethod(loginContext,
-                shibSession);
-        if (authenticationMethod != null) {
-            loginContext.setAuthenticationDuration(authenticationMethod.getAuthenticationDuration());
-            loginContext.setAuthenticationInstant(authenticationMethod.getAuthenticationInstant());
-            loginContext.setAuthenticationMethod(authenticationMethod.getAuthenticationMethod());
-            loginContext.setPrincipalAuthenticated(true);
-            loginContext.setPrincipalName(shibSession.getPrincipalName());
-            finishAuthnRequest(loginContext, httpRequest, httpResponse);
-        } else {
-            Pair<String, AuthenticationHandler> handler = getAuthenticationHandlerManager().getAuthenticationHandler(
-                    loginContext);
-
-            if (handler == null) {
-                loginContext.setPassiveAuth(false);
-                loginContext
-                        .setAuthenticationFailureMessage("No installed AuthenticationHandler can satisfy the authentication request.");
-                log.error("No installed AuthenticationHandler can satisfy the authentication request.");
-                finishAuthnRequest(loginContext, httpRequest, httpResponse);
+        if (shibSession == null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Creating shibboleth session for principal " + principalName);
+            }
+
+            InetAddress addr;
+            try {
+                addr = InetAddress.getByName(httpRequest.getRemoteAddr());
+            } catch (UnknownHostException ex) {
+                addr = null;
             }
 
-            loginContext.setAuthenticationAttempted();
-            loginContext.setAuthenticationDuration(handler.getSecond().getAuthenticationDuration());
-            loginContext.setAuthenticationMethod(handler.getFirst());
-            loginContext.setAuthenticationManagerURL(httpRequest.getRequestURI());
+            shibSession = (Session) getSessionManager().createSession(addr, loginContext.getPrincipalName());
+            loginContext.setSessionID(shibSession.getSessionID());
+            httpSession.setAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE, shibSession.getSessionID());
+        }
 
-            httpSession.setAttribute(LoginContext.LOGIN_CONTEXT_KEY, loginContext);
-            handler.getSecond().login(loginContext, httpRequest, httpResponse);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Recording authentication and service information in Shibboleth session for principal: "
+                    + principalName);
         }
+        AuthenticationMethodInformation authnMethodInfo = new AuthenticationMethodInformationImpl(loginContext
+                .getAuthenticationMethod(), new DateTime(), loginContext.getAuthenticationDuration());
+        shibSession.getAuthenticationMethods().put(authnMethodInfo.getAuthenticationMethod(), authnMethodInfo);
+
+        ServiceInformation serviceInfo = new ServiceInformationImpl(loginContext.getRelyingPartyId(), new DateTime(),
+                authnMethodInfo);
+        shibSession.getServicesInformation().put(serviceInfo.getEntityID(), serviceInfo);
+
+        shibSession.setLastActivityInstant(new DateTime());
+
+        returnToProfileHandler(loginContext, httpRequest, httpResponse);
     }
 
     /**
@@ -203,59 +344,4 @@ public class AuthenticationEngine extends HttpServlet {
 
         return null;
     }
-
-    /**
-     * Handle the "return leg" of an authentication request (i.e. clean up after an authentication handler has run).
-     * 
-     * @param loginContext The {@link LoginContext} for the new authentication request
-     * @param httpRequest The servlet request containing the authn request
-     * @param httpResponse The associated servlet response.
-     * 
-     * @throws IOException thrown if there is a problem reading/writting to the HTTP request/response
-     * @throws ServletException thrown if there is a problem transferring control to the authentication profile handler
-     */
-    protected void finishAuthnRequest(LoginContext loginContext, HttpServletRequest httpRequest,
-            HttpServletResponse httpResponse) throws ServletException, IOException {
-
-        HttpSession httpSession = httpRequest.getSession();
-        String shibSessionId = (String) httpSession.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
-        Session shibSession = null;
-        AuthenticationMethodInformation authnMethodInfo = null;
-        ServiceInformation serviceInfo = null;
-
-        if (!loginContext.getAuthenticationAttempted()) {
-            // Authentication wasn't attempted so we're using a previously established authentication method
-            shibSession = getSessionManager().getSession(shibSessionId);
-            authnMethodInfo = shibSession.getAuthenticationMethods().get(loginContext.getAuthenticationMethod());
-        } else {
-            if (shibSessionId == null) {
-                InetAddress addr;
-                try {
-                    addr = InetAddress.getByName(httpRequest.getRemoteAddr());
-                } catch (UnknownHostException ex) {
-                    addr = null;
-                }
-
-                shibSession = (Session) getSessionManager().createSession(addr, loginContext.getPrincipalName());
-                httpSession.setAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE, shibSession.getSessionID());
-
-                authnMethodInfo = new AuthenticationMethodInformationImpl(loginContext.getAuthenticationMethod(),
-                        new DateTime(), loginContext.getAuthenticationDuration());
-                shibSession.getAuthenticationMethods().put(authnMethodInfo.getAuthenticationMethod(), authnMethodInfo);
-            }
-        }
-
-        loginContext.setSessionID(shibSession.getSessionID());
-        shibSession.setLastActivityInstant(new DateTime());
-
-        serviceInfo = shibSession.getServicesInformation().get(loginContext.getRelyingPartyId());
-        if (serviceInfo == null) {
-            serviceInfo = new ServiceInformationImpl(loginContext.getRelyingPartyId(), new DateTime(), authnMethodInfo);
-        }
-
-        RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginContext.getProfileHandlerURL());
-        dispatcher.forward(httpRequest, httpResponse);
-    }
-
-    // TODO logout support
 }
\ No newline at end of file
index c0ba453..337dde3 100644 (file)
@@ -20,34 +20,30 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 /**
- * Authentication handlers are responsible for authenticating a user using a particular authentication context class and
- * logging users out for that same mechanism.
+ * Authentication handlers authenticate a user in an implementation specific manner. Some examples of this might be by
+ * collecting a user name and password and validating it against an LDAP directory or collecting and validating a client
+ * certificate or one-time password.
  * 
- * When this handler is invoked to log a user in the incoming request will contain a {@link AuthnRequest} attribute
- * registered under the name <strong>AuthnRequest</strong>. If the authentication request coming into the IdP is not a
- * SAML 2 request the receiving profile handler will translate the incoming details into a {@link AuthnRequest}.
+ * After the handler has authenticated the user it <strong>MUST</strong> bind the user's principal name to the
+ * {@link HttpServletRequest} attribute identified by {@link AuthenticationHandler#PRINCIPAL_NAME_KEY}. The handler may
+ * also bind an error message, if an error occurred during authentication to the request attribute identified by
+ * {@link AuthenticationHandler#AUTHENTICATION_ERROR_KEY}. Finally, the handler must return control to the
+ * authentication engine by invoking
+ * {@link AuthenticationEngine#returnToAuthenticationEngine(HttpServletRequest, HttpServletResponse)}. After which the
+ * authentication handler must immediately return.
  * 
- * Upon successfull authentication the handler <strong>must</strong> set a request attribute called <strong>principal</strong>
- * with the principal name of the authenticated user. It must then forward the request/response to the provided return
- * location by means of the {@link javax.servlet.RequestDispatcher.RequestDispatcher#forward(
- * javax.servlet.ServletRequest, javax.servlet.ServletResponse)} method.
- * 
- * When this handler is invoked to log a user out of the particular authentication source the handler may perform any
- * operation necessary to log a user out. When finished it must then forward the request/response to the provided return
- * location by means of the
- * {@link RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} method. This call will
- * occur before SAML logout requests have been sent to all services supporting such requests.
- * 
- * AuthentcationHandlers <strong>MUST NOT</strong> change or add any data to the user's
- * {@link javax.servlet.http.HttpSession} that persists past the process of authenticating the user, that is no
- * additional session data may be added and no existing session data may be changed when the handler redirects back to
- * the return location.
+ * Handlers <strong>MUST NOT</strong> change or add any data to the user's {@link javax.servlet.http.HttpSession} that
+ * persists past the process of authenticating the user, that is no additional session data may be added and no existing
+ * session data may be changed when the handler returns control to the authentication engine.
  */
 public interface AuthenticationHandler {
-    
+
     /** Request attribute to which user's principal name should be bound. */
     public static final String PRINCIPAL_NAME_KEY = "principal";
 
+    /** Request attribute to which an error message may be bound. */
+    public static final String AUTHENTICATION_ERROR_KEY = "authnError";
+
     /**
      * Gets the length of time, in milliseconds, after which a user authenticated by this handler should be
      * re-authenticated.
@@ -55,7 +51,7 @@ public interface AuthenticationHandler {
      * @return length of time, in milliseconds, after which a user should be re-authenticated
      */
     public long getAuthenticationDuration();
-    
+
     /**
      * Gets whether this handler supports passive authentication.
      * 
@@ -71,12 +67,12 @@ public interface AuthenticationHandler {
     public boolean supportsForceAuthentication();
 
     /**
-     * Authenticates the user making the request.
-     * @param loginContext The {@link LoginContext} for the reqeust.
+     * Authenticate the user making the request.
+     * 
      * @param httpRequest user request
      * @param httpResponse response to user
      */
-    public void login(LoginContext loginContext, HttpServletRequest httpRequest, HttpServletResponse httpResponse);
+    public void login(HttpServletRequest httpRequest, HttpServletResponse httpResponse);
 
     /**
      * Logs out the given user from the authentication mechanism represented by this handler.
index 924e7e4..b451bef 100644 (file)
@@ -29,7 +29,7 @@ import org.joda.time.DateTime;
  * 
  * Two properties are tracked by default:
  * 
- * <code>forceAuth</code> - Should user authentiation be forced. <code>passiveAuth</code> - Should user
+ * <code>forceAuth</code> - Should user authentication be forced. <code>passiveAuth</code> - Should user
  * authentication not control the UI.
  * 
  * A Map&lt;String, Object&gt; is provided to store other properties. Alternatively, a profile handler may create a
@@ -67,8 +67,8 @@ public class LoginContext implements Serializable {
     /** The ProfileHandler URL. */
     private String profileHandlerURL;
 
-    /** The AuthenticationManager's URL. */
-    private String authnManagerURL;
+    /** The authentication engine's URL. */
+    private String authnEngineURL;
 
     /** has authentication been attempted yet. */
     private boolean authnAttempted;
@@ -76,7 +76,7 @@ public class LoginContext implements Serializable {
     /** The id of the authenticated user. */
     private String principalName;
 
-    /** Did authentication succceed? */
+    /** Did authentication succeed? */
     private boolean principalAuthenticated;
 
     /** Optional failure message. */
@@ -101,7 +101,7 @@ public class LoginContext implements Serializable {
     /**
      * Creates a new instance of LoginContext.
      * 
-     * @param force if the authentication manager must reauth the user.
+     * @param force if the authentication manager must re-authenticate the user.
      * @param passive if the authentication manager must not interact with the users UI.
      */
     public LoginContext(boolean force, boolean passive) {
@@ -131,7 +131,7 @@ public class LoginContext implements Serializable {
     /**
      * Returns if authentication must be forced.
      * 
-     * @return <code>true</code> if the authentication manager must reauth the user.
+     * @return <code>true</code> if the authentication manager must re-authenticate the user.
      */
     public boolean getForceAuth() {
         return forceAuth;
@@ -149,7 +149,7 @@ public class LoginContext implements Serializable {
     /**
      * Sets if authentication must be forced.
      * 
-     * @param force if the authentication manager must reauth the user.
+     * @param force if the authentication manager must re-authenticate the user.
      */
     public void setForceAuth(boolean force) {
         forceAuth = force;
@@ -158,16 +158,16 @@ public class LoginContext implements Serializable {
     /**
      * Sets if authentication must be passive.
      * 
-     * @param passicve if the authentication manager must not interact with the users UI.
+     * @param passive if the authentication manager must not interact with the users UI.
      */
-    public void setPassiveAuth(boolean passicve) {
-        passiveAuth = passicve;
+    public void setPassiveAuth(boolean passive) {
+        passiveAuth = passive;
     }
 
     /**
      * Get an optional property object.
      * 
-     * @param key The key in the properites Map.
+     * @param key The key in the properties Map.
      * 
      * @return The object, or <code>null</code> is no object exists for the key.
      */
@@ -278,21 +278,21 @@ public class LoginContext implements Serializable {
     }
 
     /**
-     * Gets the AuthenticationManager URL.
+     * Gets the authentication engine's URL.
      * 
-     * @return the URL of the AuthenticationManager.
+     * @return the URL of the authentication engine
      */
-    public String getAuthenticationManagerURL() {
-        return authnManagerURL;
+    public String getAuthenticationEngineURL() {
+        return authnEngineURL;
     }
 
     /**
-     * Sets the AuthenticationManager's URL.
+     * Sets the authentication engine's URL.
      * 
-     * @param url the URL of the AuthenticationManager.
+     * @param url the URL of the authentication engine
      */
-    public void setAuthenticationManagerURL(String url) {
-        authnManagerURL = url;
+    public void setAuthenticationEngineURL(String url) {
+        authnEngineURL = url;
     }
 
     /**
index 5605af0..ff9b076 100644 (file)
@@ -34,6 +34,8 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.log4j.Logger;
 import org.joda.time.DateTime;
 
+import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationEngine;
+import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationHandler;
 import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
 
 /**
@@ -115,50 +117,32 @@ public class IPAddressHandler extends AbstractAuthenticationHandler {
     }
 
     /** {@inheritDoc} */
-    public void login(LoginContext loginContext, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
-
-        loginContext.setAuthenticationAttempted();
-        loginContext.setAuthenticationInstant(new DateTime());
-        loginContext.setPrincipalName(username);
+    public void login(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
 
         if (defaultDeny) {
-            handleDefaultDeny(httpRequest, httpResponse, loginContext);
+            handleDefaultDeny(httpRequest, httpResponse);
         } else {
-            handleDefaultAllow(httpRequest, httpResponse, loginContext);
+            handleDefaultAllow(httpRequest, httpResponse);
         }
 
-        // return control back to the AuthNManager.
-        try {
-            RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginContext.getAuthenticationManagerURL());
-            dispatcher.forward(httpRequest, httpResponse);
-        } catch (ServletException ex) {
-            log.error("IPAddressHandler: Error returning control to AuthnManager.", ex);
-        } catch (IOException ex) {
-            log.error("IPAddressHandler: Error returning control to AuthnManager.", ex);
-        }
+        AuthenticationEngine.returnToAuthenticationEngine(httpRequest, httpResponse);
     }
 
-    protected void handleDefaultDeny(HttpServletRequest request, HttpServletResponse response, LoginContext loginCtx) {
+    protected void handleDefaultDeny(HttpServletRequest request, HttpServletResponse response) {
 
         boolean ipAllowed = searchIpList(request);
 
         if (ipAllowed) {
-            loginCtx.setPrincipalAuthenticated(true);
-        } else {
-            loginCtx.setPrincipalAuthenticated(false);
-            loginCtx.setAuthenticationFailureMessage("The user's IP address is not in the permitted list.");
+            request.setAttribute(AuthenticationHandler.PRINCIPAL_NAME_KEY, username);
         }
     }
 
-    protected void handleDefaultAllow(HttpServletRequest request, HttpServletResponse response, LoginContext loginCtx) {
+    protected void handleDefaultAllow(HttpServletRequest request, HttpServletResponse response) {
 
         boolean ipDenied = searchIpList(request);
 
-        if (ipDenied) {
-            loginCtx.setPrincipalAuthenticated(false);
-            loginCtx.setAuthenticationFailureMessage("The user's IP address is in the deny list.");
-        } else {
-            loginCtx.setPrincipalAuthenticated(true);
+        if (!ipDenied) {
+            request.setAttribute(AuthenticationHandler.PRINCIPAL_NAME_KEY, username);
         }
     }
 
@@ -267,11 +251,9 @@ public class IPAddressHandler extends AbstractAuthenticationHandler {
 
             // ensure that the netmask isn't too large
             if ((tempAddr instanceof Inet4Address) && (masklen > 32)) {
-                throw new UnknownHostException("IPAddressHandler: Netmask is too large for an IPv4 address: " 
-                        + masklen);
+                throw new UnknownHostException("IPAddressHandler: Netmask is too large for an IPv4 address: " + masklen);
             } else if ((tempAddr instanceof Inet6Address) && masklen > 128) {
-                throw new UnknownHostException("IPAddressHandler: Netmask is too large for an IPv6 address: " 
-                        + masklen);
+                throw new UnknownHostException("IPAddressHandler: Netmask is too large for an IPv6 address: " + masklen);
             }
 
             netmask = new BitSet(addrlen);
index 4ee98d8..8e5e168 100644 (file)
@@ -25,8 +25,6 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.apache.log4j.Logger;
 
-import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
-
 /**
  * Authentication Handler that redirects to servlet protected by a Web Single-Sign-On system.
  */
@@ -57,7 +55,7 @@ public class RemoteUserAuthenticationHandler extends AbstractAuthenticationHandl
     }
 
     /** {@inheritDoc} */
-    public void login(LoginContext loginContext, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
+    public void login(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
 
         // forward control to the servlet.
         try {
index 4f362d8..f7d959e 100644 (file)
@@ -77,73 +77,73 @@ public class UsernamePasswordAuthenticationHandler extends AbstractAuthenticatio
     }
 
     /** {@inheritDoc} */
-    public void login(final edu.internet2.middleware.shibboleth.idp.authn.LoginContext loginContext,
+    public void login(
             final HttpServletRequest httpRequest, final HttpServletResponse httpResponse) {
 
-        HttpSession session = httpRequest.getSession();
-
-        // these fields will need to be set, regardless of how we branch.
-        loginContext.setAuthenticationAttempted();
-        loginContext.setAuthenticationMethod(authnMethodURI);
-
-        // If forceAuth is set, we must forward to the login JSP.
-        if (loginContext.getForceAuth()) {
-
-            if (loginContext.getPassiveAuth()) {
-                log
-                        .error("UsernamePasswordAuthenticationHandler: Unable to authenticate user: both forceAuthN and passiveAuthnN are set in the login context.");
-                redirectControl(loginContext.getAuthenticationManagerURL(), "AuthenticationManager", httpRequest,
-                        httpResponse);
-            }
-
-            session.setAttribute(JAAS_CONFIG_NAME, jaasConfigurationName);
-            redirectControl(loginURL, "login page", httpRequest, httpResponse);
-        }
-
-        // If the user has already been authenticated, forceAuth is not set,
-        // and the authentication hasn't expired, then populate the LoginCtx
-        // and return control to the AuthenticationManager.
-        // Otherwise, redirect the user to loginJSPURL to collect a username and
-        // password.
-
-        // implementation note: There is a race condition here, but I'm not sure
-        // how to avoid it. I need a way to instantiate a lock in the session to
-        // protect the
-        // username and authnInstant fields.
-
-        Object o = session.getAttribute(USERNAME);
-        if (!(o instanceof String)) {
-            log
-                    .debug("UsernamePasswordAuthenticationHandler: Username attribute found in HttpSession, but it is not a String.");
-
-            redirectControl(loginURL, "login page", httpRequest, httpResponse);
-        }
-
-        String username = (String) o;
-
-        o = session.getAttribute(AUTHN_INSTANT);
-        if (!(o instanceof DateTime)) {
-            log.debug("UsernamePasswordAuthenticationHandler: AuthnInstant attribute found in HttpSession for user "
-                    + username + ", but it is not a DateTime.");
-
-            redirectControl(loginURL, "login page", httpRequest, httpResponse);
-        }
-
-        DateTime authnInstant = (DateTime) o;
-        DateTime authnExpires = authnInstant.plusSeconds(authnDuration);
-        DateTime now = new DateTime();
-        if (now.isAfter(authnExpires)) {
-            log.info("UsernamePasswordAuthenticationHandler: Authentication has expired for user " + username);
-            redirectControl(loginURL, "login page", httpRequest, httpResponse);
-        }
-
-        // the current authentication information is still valid, so return it.
-        loginContext.setPrincipalAuthenticated(true);
-        loginContext.setPrincipalName(username);
-        loginContext.setAuthenticationInstant(authnInstant);
-
-        // XXX: adjust for the appropriate units?
-        loginContext.setAuthenticationDuration(authnDuration);
+//        HttpSession session = httpRequest.getSession();
+//
+//        // these fields will need to be set, regardless of how we branch.
+//        loginContext.setAuthenticationAttempted();
+//        loginContext.setAuthenticationMethod(authnMethodURI);
+//
+//        // If forceAuth is set, we must forward to the login JSP.
+//        if (loginContext.getForceAuth()) {
+//
+//            if (loginContext.getPassiveAuth()) {
+//                log
+//                        .error("UsernamePasswordAuthenticationHandler: Unable to authenticate user: both forceAuthN and passiveAuthnN are set in the login context.");
+//                redirectControl(loginContext.getAuthenticationEngineURL(), "AuthenticationManager", httpRequest,
+//                        httpResponse);
+//            }
+//
+//            session.setAttribute(JAAS_CONFIG_NAME, jaasConfigurationName);
+//            redirectControl(loginURL, "login page", httpRequest, httpResponse);
+//        }
+//
+//        // If the user has already been authenticated, forceAuth is not set,
+//        // and the authentication hasn't expired, then populate the LoginCtx
+//        // and return control to the AuthenticationManager.
+//        // Otherwise, redirect the user to loginJSPURL to collect a username and
+//        // password.
+//
+//        // implementation note: There is a race condition here, but I'm not sure
+//        // how to avoid it. I need a way to instantiate a lock in the session to
+//        // protect the
+//        // username and authnInstant fields.
+//
+//        Object o = session.getAttribute(USERNAME);
+//        if (!(o instanceof String)) {
+//            log
+//                    .debug("UsernamePasswordAuthenticationHandler: Username attribute found in HttpSession, but it is not a String.");
+//
+//            redirectControl(loginURL, "login page", httpRequest, httpResponse);
+//        }
+//
+//        String username = (String) o;
+//
+//        o = session.getAttribute(AUTHN_INSTANT);
+//        if (!(o instanceof DateTime)) {
+//            log.debug("UsernamePasswordAuthenticationHandler: AuthnInstant attribute found in HttpSession for user "
+//                    + username + ", but it is not a DateTime.");
+//
+//            redirectControl(loginURL, "login page", httpRequest, httpResponse);
+//        }
+//
+//        DateTime authnInstant = (DateTime) o;
+//        DateTime authnExpires = authnInstant.plusSeconds(authnDuration);
+//        DateTime now = new DateTime();
+//        if (now.isAfter(authnExpires)) {
+//            log.info("UsernamePasswordAuthenticationHandler: Authentication has expired for user " + username);
+//            redirectControl(loginURL, "login page", httpRequest, httpResponse);
+//        }
+//
+//        // the current authentication information is still valid, so return it.
+//        loginContext.setPrincipalAuthenticated(true);
+//        loginContext.setPrincipalName(username);
+//        loginContext.setAuthenticationInstant(authnInstant);
+//
+//        // XXX: adjust for the appropriate units?
+//        loginContext.setAuthenticationDuration(authnDuration);
 
     }
 
index 76ea4ad..0241634 100644 (file)
@@ -146,7 +146,7 @@ public class UsernamePasswordAuthenticationServlet extends HttpServlet {
             
             loginContext.setPrincipalAuthenticated(false);
             loginContext.setAuthenticationFailureMessage("Internal configuration error.");
-            redirectControl(loginContext.getAuthenticationManagerURL(), "AuthenticationManager", request, response);
+            redirectControl(loginContext.getAuthenticationEngineURL(), "AuthenticationManager", request, response);
         }
         
         String jassConfiguration = (String)o;
@@ -161,7 +161,7 @@ public class UsernamePasswordAuthenticationServlet extends HttpServlet {
             loginContext.setAuthenticationFailureMessage("Internal configuration error.");
             loginContext.setPrincipalAuthenticated(false);
             loginContext.setAuthenticationFailureMessage("Internal configuration error.");
-            redirectControl(loginContext.getAuthenticationManagerURL(), "AuthenticationManager", request, response);
+            redirectControl(loginContext.getAuthenticationEngineURL(), "AuthenticationManager", request, response);
             
         }
         username = (String)o;
@@ -173,14 +173,14 @@ public class UsernamePasswordAuthenticationServlet extends HttpServlet {
             loginContext.setAuthenticationFailureMessage("Internal configuration error.");
             loginContext.setPrincipalAuthenticated(false);
             loginContext.setAuthenticationFailureMessage("Internal configuration error.");
-            redirectControl(loginContext.getAuthenticationManagerURL(), "AuthenticationManager", request, response);
+            redirectControl(loginContext.getAuthenticationEngineURL(), "AuthenticationManager", request, response);
             
         }
         password = (String)o;
         
         authenticateUser(username, password, jassConfiguration, loginContext);
         password = null;
-        redirectControl(loginContext.getAuthenticationManagerURL(), "AuthenticationManager", request, response);
+        redirectControl(loginContext.getAuthenticationEngineURL(), "AuthenticationManager", request, response);
     }
 
        /**
index 2694cc9..aa098bf 100644 (file)
@@ -226,7 +226,7 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
             // UTF-8 encoding required to be supported by all JVMs.
         }
 
-        loginContext.setAuthenticationManagerURL(authenticationManagerPath);
+        loginContext.setAuthenticationEngineURL(authenticationManagerPath);
         loginContext.setProfileHandlerURL(request.getRequestURI());
         return loginContext;
     }
index 2804083..3f2fd02 100644 (file)
@@ -188,7 +188,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             authnRequest = (AuthnRequest) decoder.getSAMLMessage();
 
             Saml2LoginContext loginContext = new Saml2LoginContext(relyingParty, authnRequest);
-            loginContext.setAuthenticationManagerURL(authenticationManagerPath);
+            loginContext.setAuthenticationEngineURL(authenticationManagerPath);
             loginContext.setProfileHandlerURL(httpRequest.getRequestURI());
 
             HttpSession httpSession = httpRequest.getSession();