Prevous session is used if the user has an existing session but the SP requests an...
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 27 Nov 2008 15:46:00 +0000 (15:46 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 27 Nov 2008 15:46:00 +0000 (15:46 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/branches/REL_2@2815 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

doc/RELEASE-NOTES.txt
src/main/java/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationEngine.java

index f4c97fd..96e9ac3 100644 (file)
@@ -5,6 +5,7 @@ Changes in Release 2.1.1
 [SIDP-250] - AuthenticationEngine::returnToAuthenticationEngine() static method called before servlet init() when clustered.
 [SIDP-251[ - NPE when SAML1 Attribute Query Handler hit with GET request
 [SIDP-252] - IdPSessionFilter throws ArrayIndexOutOfBoundsException on validation of unexpected cookie
+[SIDP-257] - Prevous session is used if the user has an existing session but the SP requests an authentication method that is not currently active.
 
 Changes in Release 2.1.0
 =============================================
index c08825d..0ab6362 100644 (file)
@@ -288,14 +288,14 @@ public class AuthenticationEngine extends HttpServlet {
      */
     protected void startUserAuthentication(LoginContext loginContext, HttpServletRequest httpRequest,
             HttpServletResponse httpResponse) {
-        LOG.debug("Beginning user authentication process");
+        LOG.debug("Beginning user authentication process.");
         try {
             Session idpSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
             if (idpSession != null) {
                 LOG.debug("Existing IdP session available for principal {}", idpSession.getPrincipalName());
             }
 
-            Map<String, LoginHandler> possibleLoginHandlers = determinePossibleLoginHandlers(loginContext);
+            Map<String, LoginHandler> possibleLoginHandlers = determinePossibleLoginHandlers(idpSession, loginContext);
             LOG.debug("Possible authentication handlers for this request: {}", possibleLoginHandlers);
 
             // Filter out possible candidate login handlers by forced and passive authentication requirements
@@ -337,17 +337,19 @@ public class AuthenticationEngine extends HttpServlet {
      * Determines which configured login handlers will support the requested authentication methods.
      * 
      * @param loginContext current login context
+     * @param idpSession current user's session, or null if they don't have one
      * 
      * @return login methods that may be used to authenticate the user
      * 
      * @throws AuthenticationException thrown if no login handler meets the given requirements
      */
-    protected Map<String, LoginHandler> determinePossibleLoginHandlers(LoginContext loginContext)
+    protected Map<String, LoginHandler> determinePossibleLoginHandlers(Session idpSession, LoginContext loginContext)
             throws AuthenticationException {
         Map<String, LoginHandler> supportedLoginHandlers = new HashMap<String, LoginHandler>(handlerManager
                 .getLoginHandlers());
-        LOG.trace("Supported login handlers: {}", supportedLoginHandlers);
-        LOG.trace("Requested authentication methods: {}", loginContext.getRequestedAuthenticationMethods());
+        LOG.debug("Filtering configured login handlers by requested athentication methods.");
+        LOG.debug("Configured LoginHandlers: {}", supportedLoginHandlers);
+        LOG.debug("Requested authentication methods: {}", loginContext.getRequestedAuthenticationMethods());
 
         // If no preferences Authn method preference is given, then we're free to use any
         if (loginContext.getRequestedAuthenticationMethods().isEmpty()) {
@@ -355,6 +357,26 @@ public class AuthenticationEngine extends HttpServlet {
             return supportedLoginHandlers;
         }
 
+        // If the previous session handler is configured, the user has an existing session, and the SP requested
+        // that a certain set of authentication methods be used then we need to check to see if the user has
+        // authenticated with one or more of those methods, if not we can't use the previous session handler
+        if (supportedLoginHandlers.containsKey(AuthnContext.PREVIOUS_SESSION_AUTHN_CTX) && idpSession != null
+                && loginContext.getRequestedAuthenticationMethods() != null) {
+            boolean retainPreviousSession = false;
+
+            Map<String, AuthenticationMethodInformation> currentAuthnMethods = idpSession.getAuthenticationMethods();
+            for (String currentAuthnMethod : currentAuthnMethods.keySet()) {
+                if (loginContext.getRequestedAuthenticationMethods().contains(currentAuthnMethod)) {
+                    retainPreviousSession = true;
+                    break;
+                }
+            }
+
+            if (!retainPreviousSession) {
+                supportedLoginHandlers.remove(AuthnContext.PREVIOUS_SESSION_AUTHN_CTX);
+            }
+        }
+
         // Otherwise we need to filter all the mechanism supported by the IdP so that only the request types are left
         // Previous session handler is a special case, we always to keep that around if it's configured
         Iterator<Entry<String, LoginHandler>> supportedLoginHandlerItr = supportedLoginHandlers.entrySet().iterator();