Add authentication request and relying party ID
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 6 Jun 2007 15:35:11 +0000 (15:35 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 6 Jun 2007 15:35:11 +0000 (15:35 +0000)
Make serializable
Checkystyle fixes

git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2235 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationManager.java
src/edu/internet2/middleware/shibboleth/idp/authn/LoginContext.java
src/edu/internet2/middleware/shibboleth/idp/authn/Saml2LoginContext.java

index 0d32461..05788e5 100644 (file)
@@ -43,331 +43,287 @@ import org.springframework.web.servlet.HttpServletBean;
  */
 public class AuthenticationManager extends HttpServletBean {
 
-       /** log4j. */
-       private static final Logger log = Logger.getLogger(AuthenticationManager.class);
-
-       /** SessionManager to be used. */
-       private SessionManager sessionMgr;
-
-       /** Map of URIs onto AuthenticationHandlerInfo. */
-       private Map<String, AuthenticationHandler> handlerMap = new ConcurrentHashMap<String, AuthenticationHandler>();
-
-       /** The default AuthenticationHandler. */
-       private AuthenticationHandler defaultHandler;
-
-       /* The URI for the default AuthenticationHandler. */
-       private String defaultHandlerURI;
-
-       /**
-        * Gets the session manager to be used.
-        * 
-        * @return session manager to be used
-        */
-       public SessionManager getSessionManager() {
-               return sessionMgr;
-       }
-
-       /**
-        * Sets the session manager to be used.
-        * 
-        * @param manager
-        *            session manager to be used.
-        */
-       public void setSessionManager(final SessionManager manager) {
-               sessionMgr = manager;
-       }
-
-       /**
-        * Get the map of {@link AuthenticationHandlers}.
-        * 
-        * @return The map of AuthenticationHandlers
-        */
-       public Map<String, AuthenticationHandler> getHandlerMap() {
-
-               return new FastMap<String, AuthenticationHandler>(handlerMap);
-       }
-
-       /**
-        * Set the {@link AuthenticationHandler} map.
-        * 
-        * @param handlerMap
-        *            The Map of URIs to AuthenticationHandlers
-        */
-       public void setHandlerMap(
-                       final Map<String, AuthenticationHandler> handlerMap) {
-
-               for (String uri : handlerMap.keySet()) {
-                       addHandlerMapping(uri, handlerMap.get(uri));
-               }
-       }
-
-       /**
-        * Add a <code>&lt;String:AuthenticationHandler&gr;</code> mapping to the
-        * AuthenticationManager's table. If a mapping for the URI already exists,
-        * it will be overwritten.
-        * 
-        * The URI SHOULD be from the saml-autn-context-2.0-os
-        * 
-        * @param uri
-        *            A URI identifying the authentcation method.
-        * @param handler
-        *            The AuthenticationHandler.
-        */
-       public void addHandlerMapping(String uri, AuthenticationHandler handler) {
-
-               if (uri == null || handler == null) {
-                       return;
-               }
-
-               log.debug("AuthenticationManager: Registering " + handler.getClass().getName() + " for "
-                                               + uri);
-
-               handlerMap.put(uri, handler);
-       }
-
-       /**
-        * Register the default {@link AuthenticationHandler}.
-        * 
-        * @param uri
-        *            The URI of the default authentication handler (from
-        *            saml-authn-context-2.0-os)
-        * @param handler
-        *            The default {@link AuthenticationHandler}.
-        */
-       public void setDefaultHandler(String uri, AuthenticationHandler handler) {
-
-               log.debug("AuthenticationManager: Registering default handler "
-                                               + handler.getClass().getName());
-
-               defaultHandler = handler;
-               defaultHandlerURI = uri;
-       }
-
-       /**
-        * Remove a <String:AuthenticationHandler> mapping from the
-        * AuthenticationManager's table.
-        * 
-        * The URI SHOULD be from the saml-authn-context-2.0-os
-        * 
-        * @param uri
-        *            A URI identifying the authentcation method.
-        */
-       public void removeHandlerMapping(String uri) {
-
-               if (uri == null) {
-                       return;
-               }
-
-               log.debug("AuthenticationManager: Unregistering handler for " + uri);
-
-               handlerMap.remove(uri);
-       }
-
-       /**
-        * Primary entrypoint for the AuthnManager.
-        * 
-        * @param req
-        *            The ServletRequest.
-        * @param resp
-        *            The ServletResponse.
-        */
-       public void doPost(HttpServletRequest req, HttpServletResponse resp)
-                       throws ServletException, IOException {
-
-               if (req == null || resp == null) {
-                       log.error("AuthenticationManager: Invalid parameters in AuthenticationManager's doPost().");
-                       return;
-               }
-
-               HttpSession httpSession = req.getSession();
-               Object o = httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
-                
-                if (o == null || !(o instanceof LoginContext)) {
-                       log.error("AuthenticationManager: Invalid login context object found in HttpSession.");
-                       return;
-               }
-               LoginContext loginContext = (LoginContext) o;
-
-               // If authentication has been attempted, don't try it again.
-               if (loginContext.getAuthenticationAttempted()) {
-                       handleNewAuthnRequest(loginContext, req, resp);
-               } else {
-                       finishAuthnRequest(loginContext, req, resp);
-               }
-       }
-
-       /**
-        * Handle a new authentication request.
-        * 
-        * @param loginContext
-        *            The {@link LoginContext} for the new authentication request
-        * @param servletRequest
-        *            The servlet request containing the authn request
-        * @param servletResponse
-        *            The associated servlet response.
-        */
-       private void handleNewAuthnRequest(final LoginContext loginContext,
-                       final HttpServletRequest servletRequest,
-                       final HttpServletResponse servletResponse) throws ServletException,
-                       IOException {
-
-               boolean forceAuthN = loginContext.getForceAuth();
-               boolean passiveAuthN = loginContext.getPassiveAuth();
-
-               // set that authentication has been attempted, to prevent processing
-               // loops
-               loginContext.setAuthenticationAttempted();
-
-               // if the profile handler set a list of requested authn methods,
-               // evaluate them. otherwise, evaluate the default handler.
-               String[] requestedAuthnMethods = loginContext
-                               .getRequestedAuthenticationMethods();
-               AuthenticationHandler handler = null;
-
-               if (requestedAuthnMethods == null) {
-
-                       // if no authn methods were specified, try the default handler
-
-                       if (evaluateHandler(defaultHandler, "default", forceAuthN,
-                                       passiveAuthN)) {
-                               handler = defaultHandler;
-                               loginContext.setAuthenticationMethod(defaultHandlerURI);
-                       }
-
-               } else {
-
-                       // evaluate all requested authn methods until we find a match.
-
-                       for (String authnMethodURI : requestedAuthnMethods) {
-
-                               AuthenticationHandler candidateHandler = handlerMap
-                                               .get(authnMethodURI);
-                               if (candidateHandler == null) {
-                                       log.debug("AuthenticationManager:  No registered authentication handlers can satisfy the "
-                                                                       + " requested authentication method "
-                                                                       + authnMethodURI);
-                                       continue;
-                               }
-
-                               if (evaluateHandler(candidateHandler, authnMethodURI,
-                                               forceAuthN, passiveAuthN)) {
-
-                                       // we found a match. stop iterating.
-                                       handler = candidateHandler;
-                                       log.info("AuthenticationManager: Using authentication handler "
-                                                       + handler.getClass().getName()
-                                                       + " for authentication method " + authnMethodURI);
-                                       loginContext.setAuthenticationMethod(authnMethodURI);
-                                       break;
-                               }
-                       }
-               }
-
-               // if no acceptable handler was found, abort.
-               if (handler == null) {
-                       loginContext.setAuthenticationOK(false);
-                       loginContext.setAuthenticationFailureMessage("No installed AuthenticationHandler can satisfy the authentication request.");
-
-                       log.error("AuthenticationManager:  No registered authentication handlers could satisify any requested "
-                                                       + "authentication methods. Unable to process authentication request.");
-
-                       RequestDispatcher dispatcher = servletRequest
-                                       .getRequestDispatcher(loginContext.getProfileHandlerURL());
-                       dispatcher.forward(servletRequest, servletResponse);
-               }
-
-               // otherwise, forward control to the AuthenticationHandler
-               loginContext.setAuthenticationManagerURL(servletRequest.getRequestURI());
-               handler.login(servletRequest, servletResponse, loginContext);
-       }
-
-       /**
-        * Handle the "return leg" of an authentication request (i.e. clean up after
-        * an authentication handler has run).
-        * 
-        */
-       private void finishAuthnRequest(final LoginContext loginContext,
-                       final HttpServletRequest servletRequest,
-                       final HttpServletResponse servletResponse) throws ServletException,
-                       IOException {
-
-               // if authentication was successful, the authentication handler should
-               // have updated the LoginContext with additional information. Use that
-               // info to create a Session.
-               if (loginContext.getAuthenticationOK()) {
-
-                       AuthenticationMethodInformation authMethodInfo = new AuthenticationMethodInformationImpl(
-                                       loginContext.getAuthenticationMethod(), loginContext
-                                                       .getAuthenticationInstant(), loginContext
-                                                       .getAuthenticationDuration());
-
-                       InetAddress addr;
-                       try {
-                               addr = InetAddress.getByName(servletRequest.getRemoteAddr());
-                       } catch (Exception ex) {
-                               addr = null;
-                       }
-
-                       Session shibSession = (Session) sessionMgr.createSession(addr,
-                                       loginContext.getUserID());
-                       List<AuthenticationMethodInformation> authMethods = shibSession
-                                       .getAuthenticationMethods();
-                       authMethods.add(authMethodInfo);
-                       loginContext.setSessionID(shibSession.getSessionID());
-               }
-
-               RequestDispatcher dispatcher = servletRequest
-                               .getRequestDispatcher(loginContext.getProfileHandlerURL());
-               dispatcher.forward(servletRequest, servletResponse);
-       }
-
-       /**
-        * "Stub" method for handling LogoutRequest.
-        */
-       private void handleLogoutRequest(final HttpServletRequest servletRequest,
-                       final HttpServletResponse servletResponse) throws ServletException,
-                       IOException {
-
-       }
-
-       /**
-        * Evaluate an authenticationhandler against a set of evaluation criteria.
-        * 
-        * @param handler
-        *            A candiate {@link AuthenticationHandler}
-        * @param description
-        *            A description of the handler
-        * @param forceAuthN
-        *            Is (re)authentication forced?
-        * @param passiveAuthN
-        *            Can the AuthenticationHandler take control of the UI
-        * 
-        * @return <code>true</code> if handler meets the criteria, otherwise
-        *         <code>false</code>
-        */
-       private boolean evaluateHandler(final AuthenticationHandler handler,
-                       String description, boolean forceAuthN, boolean passiveAuthN) {
-
-               if (handler == null) {
-                       return false;
-               }
-
-               if (forceAuthN && !handler.supportsForceAuthentication()) {
-                       log.debug("AuthenticationManager: The RequestedAuthnContext required forced authentication, "
-                                                       + "but the "
-                                                       + description
-                                                       + " handler does not support that feature.");
-                       return false;
-               }
-
-               if (passiveAuthN && !handler.supportsPassive()) {
-                       log.debug("AuthenticationManager:  The RequestedAuthnContext required passive authentication, "
-                                                       + "but the "
-                                                       + description
-                                                       + " handler does not support that feature.");
-                       return false;
-               }
-
-               return true;
-       }
+    /** log4j. */
+    private final Logger log = Logger.getLogger(AuthenticationManager.class);
+
+    /** SessionManager to be used. */
+    private SessionManager sessionMgr;
+
+    /** Map of URIs onto AuthenticationHandlerInfo. */
+    private Map<String, AuthenticationHandler> handlerMap = new ConcurrentHashMap<String, AuthenticationHandler>();
+
+    /** The default AuthenticationHandler. */
+    private AuthenticationHandler defaultHandler;
+
+    /** The URI for the default AuthenticationHandler. */
+    private String defaultHandlerURI;
+
+    /**
+     * Gets the session manager to be used.
+     * 
+     * @return session manager to be used
+     */
+    public SessionManager getSessionManager() {
+        return sessionMgr;
+    }
+
+    /**
+     * Sets the session manager to be used.
+     * 
+     * @param manager session manager to be used.
+     */
+    public void setSessionManager(final SessionManager manager) {
+        sessionMgr = manager;
+    }
+
+    /**
+     * Get the map of {@link AuthenticationHandlers}.
+     * 
+     * @return The map of AuthenticationHandlers
+     */
+    public Map<String, AuthenticationHandler> getHandlerMap() {
+
+        return new FastMap<String, AuthenticationHandler>(handlerMap);
+    }
+
+    /**
+     * Set the {@link AuthenticationHandler} map.
+     * 
+     * @param handlerMap The Map of URIs to AuthenticationHandlers
+     */
+    public void setHandlerMap(final Map<String, AuthenticationHandler> handlerMap) {
+
+        for (String uri : handlerMap.keySet()) {
+            addHandlerMapping(uri, handlerMap.get(uri));
+        }
+    }
+
+    /**
+     * Add a <code>&lt;String:AuthenticationHandler&gr;</code> mapping to the AuthenticationManager's table. If a
+     * mapping for the URI already exists, it will be overwritten.
+     * 
+     * The URI SHOULD be from the saml-autn-context-2.0-os
+     * 
+     * @param uri A URI identifying the authentcation method.
+     * @param handler The AuthenticationHandler.
+     */
+    public void addHandlerMapping(String uri, AuthenticationHandler handler) {
+
+        if (uri == null || handler == null) {
+            return;
+        }
+
+        log.debug("AuthenticationManager: Registering " + handler.getClass().getName() + " for " + uri);
+
+        handlerMap.put(uri, handler);
+    }
+
+    /**
+     * Register the default {@link AuthenticationHandler}.
+     * 
+     * @param uri The URI of the default authentication handler (from saml-authn-context-2.0-os)
+     * @param handler The default {@link AuthenticationHandler}.
+     */
+    public void setDefaultHandler(String uri, AuthenticationHandler handler) {
+
+        log.debug("AuthenticationManager: Registering default handler " + handler.getClass().getName());
+
+        defaultHandler = handler;
+        defaultHandlerURI = uri;
+    }
+
+    /**
+     * Remove a <String:AuthenticationHandler> mapping from the AuthenticationManager's table.
+     * 
+     * The URI SHOULD be from the saml-authn-context-2.0-os
+     * 
+     * @param uri A URI identifying the authentcation method.
+     */
+    public void removeHandlerMapping(String uri) {
+
+        if (uri == null) {
+            return;
+        }
+
+        log.debug("AuthenticationManager: Unregistering handler for " + uri);
+
+        handlerMap.remove(uri);
+    }
+
+    /**
+     * Primary entrypoint for the AuthnManager.
+     * 
+     * @param req The ServletRequest.
+     * @param resp The ServletResponse.
+     */
+    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+        if (req == null || resp == null) {
+            log.error("AuthenticationManager: Invalid parameters in AuthenticationManager's doPost().");
+            return;
+        }
+
+        HttpSession httpSession = req.getSession();
+        Object o = httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
+
+        if (o == null || !(o instanceof LoginContext)) {
+            log.error("AuthenticationManager: Invalid login context object found in HttpSession.");
+            return;
+        }
+        LoginContext loginContext = (LoginContext) o;
+
+        // If authentication has been attempted, don't try it again.
+        if (loginContext.getAuthenticationAttempted()) {
+            handleNewAuthnRequest(loginContext, req, resp);
+        } else {
+            finishAuthnRequest(loginContext, req, resp);
+        }
+    }
+
+    /**
+     * Handle a new authentication request.
+     * 
+     * @param loginContext The {@link LoginContext} for the new authentication request
+     * @param servletRequest The servlet request containing the authn request
+     * @param servletResponse The associated servlet response.
+     */
+    private void handleNewAuthnRequest(final LoginContext loginContext, final HttpServletRequest servletRequest,
+            final HttpServletResponse servletResponse) throws ServletException, IOException {
+
+        boolean forceAuthN = loginContext.getForceAuth();
+        boolean passiveAuthN = loginContext.getPassiveAuth();
+
+        // set that authentication has been attempted, to prevent processing
+        // loops
+        loginContext.setAuthenticationAttempted();
+
+        // if the profile handler set a list of requested authn methods,
+        // evaluate them. otherwise, evaluate the default handler.
+        List<String> requestedAuthnMethods = loginContext.getRequestedAuthenticationMethods();
+        AuthenticationHandler handler = null;
+
+        if (requestedAuthnMethods == null) {
+
+            // if no authn methods were specified, try the default handler
+
+            if (evaluateHandler(defaultHandler, "default", forceAuthN, passiveAuthN)) {
+                handler = defaultHandler;
+                loginContext.setAuthenticationMethod(defaultHandlerURI);
+            }
+
+        } else {
+
+            // evaluate all requested authn methods until we find a match.
+
+            for (String authnMethodURI : requestedAuthnMethods) {
+
+                AuthenticationHandler candidateHandler = handlerMap.get(authnMethodURI);
+                if (candidateHandler == null) {
+                    log.debug("AuthenticationManager:  No registered authentication handlers can satisfy the "
+                            + " requested authentication method " + authnMethodURI);
+                    continue;
+                }
+
+                if (evaluateHandler(candidateHandler, authnMethodURI, forceAuthN, passiveAuthN)) {
+
+                    // we found a match. stop iterating.
+                    handler = candidateHandler;
+                    log.info("AuthenticationManager: Using authentication handler " + handler.getClass().getName()
+                            + " for authentication method " + authnMethodURI);
+                    loginContext.setAuthenticationMethod(authnMethodURI);
+                    break;
+                }
+            }
+        }
+
+        // if no acceptable handler was found, abort.
+        if (handler == null) {
+            loginContext.setAuthenticationOK(false);
+            loginContext
+                    .setAuthenticationFailureMessage("No installed AuthenticationHandler can satisfy the authentication request.");
+
+            log.error("AuthenticationManager:  No registered authentication handlers could satisify any requested "
+                    + "authentication methods. Unable to process authentication request.");
+
+            RequestDispatcher dispatcher = servletRequest.getRequestDispatcher(loginContext.getProfileHandlerURL());
+            dispatcher.forward(servletRequest, servletResponse);
+        }
+
+        // otherwise, forward control to the AuthenticationHandler
+        loginContext.setAuthenticationManagerURL(servletRequest.getRequestURI());
+        handler.login(servletRequest, servletResponse, loginContext);
+    }
+
+    /**
+     * Handle the "return leg" of an authentication request (i.e. clean up after an authentication handler has run).
+     * 
+     */
+    private void finishAuthnRequest(final LoginContext loginContext, final HttpServletRequest servletRequest,
+            final HttpServletResponse servletResponse) throws ServletException, IOException {
+
+        // if authentication was successful, the authentication handler should
+        // have updated the LoginContext with additional information. Use that
+        // info to create a Session.
+        if (loginContext.getAuthenticationOK()) {
+
+            AuthenticationMethodInformation authMethodInfo = new AuthenticationMethodInformationImpl(loginContext
+                    .getAuthenticationMethod(), loginContext.getAuthenticationInstant(), loginContext
+                    .getAuthenticationDuration());
+
+            InetAddress addr;
+            try {
+                addr = InetAddress.getByName(servletRequest.getRemoteAddr());
+            } catch (Exception ex) {
+                addr = null;
+            }
+
+            Session shibSession = (Session) sessionMgr.createSession(addr, loginContext.getUserID());
+            List<AuthenticationMethodInformation> authMethods = shibSession.getAuthenticationMethods();
+            authMethods.add(authMethodInfo);
+            loginContext.setSessionID(shibSession.getSessionID());
+        }
+
+        RequestDispatcher dispatcher = servletRequest.getRequestDispatcher(loginContext.getProfileHandlerURL());
+        dispatcher.forward(servletRequest, servletResponse);
+    }
+
+    /**
+     * "Stub" method for handling LogoutRequest.
+     */
+    private void handleLogoutRequest(final HttpServletRequest servletRequest, final HttpServletResponse servletResponse)
+            throws ServletException, IOException {
+
+    }
+
+    /**
+     * Evaluate an authenticationhandler against a set of evaluation criteria.
+     * 
+     * @param handler A candiate {@link AuthenticationHandler}
+     * @param description A description of the handler
+     * @param forceAuthN Is (re)authentication forced?
+     * @param passiveAuthN Can the AuthenticationHandler take control of the UI
+     * 
+     * @return <code>true</code> if handler meets the criteria, otherwise <code>false</code>
+     */
+    private boolean evaluateHandler(final AuthenticationHandler handler, String description, boolean forceAuthN,
+            boolean passiveAuthN) {
+
+        if (handler == null) {
+            return false;
+        }
+
+        if (forceAuthN && !handler.supportsForceAuthentication()) {
+            log.debug("AuthenticationManager: The RequestedAuthnContext required forced authentication, " + "but the "
+                    + description + " handler does not support that feature.");
+            return false;
+        }
+
+        if (passiveAuthN && !handler.supportsPassive()) {
+            log.debug("AuthenticationManager:  The RequestedAuthnContext required passive authentication, "
+                    + "but the " + description + " handler does not support that feature.");
+            return false;
+        }
+
+        return true;
+    }
 }
index d8ae500..3aef09c 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.authn;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.joda.time.DateTime;
 
 /**
- * Login context created by a profile handler and interpreted by the
- * authentication package.
+ * Login context created by a profile handler and interpreted by the authentication package.
  * 
  * Two properties are tracked by default:
  * 
- * <code>forceAuth</code> - Should user authentiation be forced.
- * <code>passiveAuth</code> - Should user authentication not control the UI.
+ * <code>forceAuth</code> - Should user authentiation 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 subclass of LoginContext with
- * extra fields.
+ * A Map&lt;String, Object&gt; is provided to store other properties. Alternatively, a profile handler may create a
+ * subclass of LoginContext with extra fields.
  * 
- * LoginContexts should be created by a profile handler when authentication is
- * needed. Once control has returned to the profile handler, it should remove
- * the LoginContext from the HttpSession.
+ * LoginContexts should be created by a profile handler when authentication is needed. Once control has returned to the
+ * profile handler, it should remove the LoginContext from the HttpSession.
  * 
- * The {@link AuthenticationManager} or an {@link AuthenticationHandler} should
- * set the {@link LoginContext#setAuthenticationAttempted()},
- * {@link LoginContext#setAuthnOK(boolean)},
- * {@link LoginContext#setAuthnFailure(String)},
- * {@link LoginContext#{setAuthenticationDuration(long)}
+ * The {@link AuthenticationManager} or an {@link AuthenticationHandler} should set the
+ * {@link LoginContext#setAuthenticationAttempted()}, {@link LoginContext#setAuthnOK(boolean)},
+ * {@link LoginContext#setAuthnFailure(String)}, {@link LoginContext#{setAuthenticationDuration(long)}
  * {@link LoginContext#setAuthenticationInstant(DateTime)} appropriately.
  * 
  */
-public class LoginContext {
-
-       /** the key in a HttpSession where login contexts are stored */
-       public static final String LOGIN_CONTEXT_KEY = "shib2.logincontext";
-
-       /** Should user authentication be forced */
-       protected boolean forceAuth = false;
-
-       /** Must authentication not interact with the UI */
-       protected boolean passiveAuth = false;
-
-       /** a catch-all map for other properties */
-       protected Map<String, Object> propsMap = new ConcurrentHashMap<String, Object>();;
-
-       /** The ProfileHandler URL */
-       protected String profileHandlerURL;
-
-       /** The AuthenticationManager's URL */
-       protected String authnManagerURL;
-
-       /** has authentication been attempted yet */
-       protected boolean authnAttempted = false;
-
-       /** The id of the authenticated user */
-       protected String userID;
-
-       /** Did authentication succceed? */
-       protected boolean authenticationOK;
-
-       /** Optional failure message */
-       protected String authnFailureMessage;
-
-       /** The instant of authentication */
-       protected DateTime authnInstant;
-
-       /** The duration of authentication */
-       protected long authnDuration;
-
-       /** The method used to authenticate the user */
-       protected String authnMethod;
-
-       /** The session id */
-       protected String sessionID;
-
-       /** Creates a new instance of LoginContext */
-       public LoginContext() {
-       }
-
-       /**
-        * Creates a new instance of LoginContext
-        * 
-        * @param forceAuth
-        *            if the authentication manager must reauth the user.
-        * @param passiveAuth
-        *            if the authentication manager must not interact with the users
-        *            UI.
-        */
-       public LoginContext(boolean forceAuth, boolean passiveAuth) {
-
-               forceAuth = forceAuth;
-               passiveAuth = passiveAuth;
-       }
-
-       /**
-        * Returns if authentication must be forced.
-        * 
-        * @return <code>true</code> if the authentication manager must reauth the
-        *         user.
-        */
-       public boolean getForceAuth() {
-               return forceAuth;
-       }
-
-       /**
-        * Returns if authentication must be passive.
-        * 
-        * @return <code>true</code> if the authentication manager must not
-        *         interact with the users UI.
-        */
-       public boolean getPassiveAuth() {
-               return passiveAuth;
-       }
-
-       /**
-        * Sets if authentication must be forced.
-        * 
-        * @param forceAuth
-        *            if the authentication manager must reauth the user.
-        */
-       public void setForceAuth(boolean forceAuth) {
-               this.forceAuth = forceAuth;
-       }
-
-       /**
-        * Sets if authentication must be passive.
-        * 
-        * @param passiveAuth
-        *            if the authentication manager must not interact with the users
-        *            UI.
-        */
-       public void setPassiveAuth(boolean passiveAuth) {
-               this.passiveAuth = passiveAuth;
-       }
-
-       /**
-        * Get an optional property object.
-        * 
-        * @param key
-        *            The key in the properites Map.
-        * 
-        * @return The object, or <code>null</code> is no object exists for the
-        *         key.
-        */
-       public Object getProperty(String key) {
-               return propsMap.get(key);
-       }
-
-       /**
-        * Sets an optional property object.
-        * 
-        * If an object is already associated with key, it will be overwritten.
-        * 
-        * @param key
-        *            The key to set.
-        * @param obj
-        *            The object to associate with key.
-        */
-       public void setProperty(String key, final Object obj) {
-               propsMap.put(key, obj);
-       }
-
-       /**
-        * Sets if authentication succeeded.
-        * 
-        * @param authnOK
-        *            if authentication succeeded;
-        */
-       public void setAuthenticationOK(boolean authnOK) {
-               this.authenticationOK = authnOK;
-       }
-
-       /**
-        * Returns if authentication succeeded.
-        * 
-        * @return <code>true</code> is the user was successfully authenticated.
-        */
-       public boolean getAuthenticationOK() {
-               return authenticationOK;
-       }
-
-       /**
-        * Sets the optional authentication failure message.
-        * 
-        * @param failureMessage
-        *            A description of why authN failed.
-        */
-       public void setAuthenticationFailureMessage(String failureMessage) {
-               authnFailureMessage = failureMessage;
-       }
-
-       /**
-        * Returns the optional authentication failure message.
-        * 
-        * @return The failure message, or <code>null</code> is none was set.
-        */
-       public String getAuthenticationFailureMessage() {
-               return authnFailureMessage;
-       }
-
-       /**
-        * Set if authentication has been attempted.
-        * 
-        * This method should be called by an {@link AuthenticationHandler} while
-        * processing a request.
-        */
-       public void setAuthenticationAttempted() {
-               authnAttempted = true;
-       }
-
-       /**
-        * Returns if authentication has been attempted for this user.
-        */
-       public boolean getAuthenticationAttempted() {
-               return authnAttempted;
-       }
-
-       /**
-        * Sets the ID of the authenticated user.
-        * 
-        * @param userID
-        *            The userid.
-        */
-       public void setUserID(String userID) {
-               this.userID = userID;
-       }
-
-       /**
-        * Returns the ID of the authenticated user.
-        * 
-        * @return the ID of the user, or <code>null</code> if authentication
-        *         failed.
-        */
-       public String getUserID() {
-               return userID;
-       }
-
-       /**
-        * Gets the ProfileHandler URL.
-        * 
-        * @return the URL of the profile handler that is invoking the
-        *         Authentication Manager.
-        */
-       public String getProfileHandlerURL() {
-               return profileHandlerURL;
-       }
-
-       /**
-        * Sets the ProfileHandler URL.
-        * 
-        * @param profileHandlerURL
-        *            The URL of the profile handler that invoked the
-        *            AuthenticationManager/
-        */
-       public void setProfileHandlerURL(String profileHandlerURL) {
-               this.profileHandlerURL = profileHandlerURL;
-       }
-
-       /**
-        * Gets the AuthenticationManager URL.
-        * 
-        * @return the URL of the AuthenticationManager.
-        */
-       public String getAuthenticationManagerURL() {
-               return authnManagerURL;
-       }
-
-       /**
-        * Sets the AuthenticationManager's URL.
-        * 
-        * @param authnManagerURL
-        *            the URL of the AuthenticationManager.
-        */
-       public void setAuthenticationManagerURL(String authnManagerURL) {
-               this.authnManagerURL = authnManagerURL;
-       }
-
-       /**
-        * Gets the authentication instant.
-        * 
-        * @return The instant of authentication, or <code>null</code> if none was
-        *         set.
-        */
-       public DateTime getAuthenticationInstant() {
-               return authnInstant;
-       }
-
-       /**
-        * Sets the authentication instant.
-        * 
-        * @param authnInstant
-        *            The instant of authentication.
-        */
-       public void setAuthenticationInstant(final DateTime authnInstant) {
-               this.authnInstant = authnInstant;
-       }
-
-       /**
-        * Gets the duration of authentication.
-        * 
-        * @return The duration of authentication, or zero if none was set.
-        */
-       public long getAuthenticationDuration() {
-               return authnDuration;
-       }
-
-       /**
-        * Sets the duration of authentication.
-        * 
-        * @param authnDuration
-        *            The duration of authentication.
-        */
-       public void setAuthenticationDuration(long authnDuration) {
-               this.authnDuration = authnDuration;
-       }
-
-       /**
-        * Gets the method used to authenticate the user.
-        * 
-        * @return The method used to authenticate the user.
-        */
-       public String getAuthenticationMethod() {
-               return authnMethod;
-       }
-
-       /**
-        * Sets the method used to authenticate the user.
-        * 
-        * @param authnMethod
-        *            The method used to authenticate the user.
-        */
-       public void setAuthenticationMethod(String authnMethod) {
-               this.authnMethod = authnMethod;
-       }
-
-       /**
-        * Gets the {@link Session} ID
-        * 
-        * @return the Session id.
-        */
-       public String getSessionID() {
-               return sessionID;
-       }
-
-       /**
-        * Sets the {@link Session} ID
-        * 
-        * @param sessionID
-        *            the Session ID
-        */
-       public void setSessionID(String sessionID) {
-               this.sessionID = sessionID;
-       }
-
-       /**
-        * Return the acceptable authentication handler URIs for authenticating this
-        * user. If no authentication methods are preferred, this method will return
-        * <code>null</code>.
-        * 
-        * @return an array of URIs, or <code>null</code>.
-        */
-       public String[] getRequestedAuthenticationMethods() {
-
-               return null;
-       }
+public class LoginContext implements Serializable {
+
+    /** the key in a HttpSession where login contexts are stored. */
+    public static final String LOGIN_CONTEXT_KEY = "shib2.logincontext";
+    
+    /** Serial version UID. */
+    private static final long serialVersionUID = 4268661186941572372L;
+
+    /** Entity ID of the relying party. */
+    private String relyingPartyId;
+
+    /** Should user authentication be forced. */
+    private boolean forceAuth;
+
+    /** Must authentication not interact with the UI. */
+    private boolean passiveAuth;
+
+    /** a catch-all map for other properties. */
+    private Map<String, Serializable> propsMap = new ConcurrentHashMap<String, Serializable>();
+
+    /** The ProfileHandler URL. */
+    private String profileHandlerURL;
+
+    /** The AuthenticationManager's URL. */
+    private String authnManagerURL;
+
+    /** has authentication been attempted yet. */
+    private boolean authnAttempted;
+
+    /** The id of the authenticated user. */
+    private String userID;
+
+    /** Did authentication succceed? */
+    private boolean authenticationOK;
+
+    /** Optional failure message. */
+    private String authnFailureMessage;
+
+    /** The instant of authentication. */
+    private DateTime authnInstant;
+
+    /** The duration of authentication. */
+    private long authnDuration;
+
+    /** The method used to authenticate the user. */
+    private String authnMethod;
+
+    /** The session id. */
+    private String sessionID;
+
+    /** Creates a new instance of LoginContext. */
+    public LoginContext() {
+    }
+
+    /**
+     * Creates a new instance of LoginContext.
+     * 
+     * @param force if the authentication manager must reauth the user.
+     * @param passive if the authentication manager must not interact with the users UI.
+     */
+    public LoginContext(boolean force, boolean passive) {
+
+        forceAuth = force;
+        passiveAuth = passive;
+    }
+
+    /**
+     * Gets the entity ID of the relying party.
+     * 
+     * @return entity ID of the relying party
+     */
+    public String getRelyingPartyId() {
+        return relyingPartyId;
+    }
+
+    /**
+     * Gets the entity ID of the relying party.
+     * 
+     * @param id entity ID of the relying party
+     */
+    public void setRelyingParty(String id) {
+        relyingPartyId = id;
+    }
+
+    /**
+     * Returns if authentication must be forced.
+     * 
+     * @return <code>true</code> if the authentication manager must reauth the user.
+     */
+    public boolean getForceAuth() {
+        return forceAuth;
+    }
+
+    /**
+     * Returns if authentication must be passive.
+     * 
+     * @return <code>true</code> if the authentication manager must not interact with the users UI.
+     */
+    public boolean getPassiveAuth() {
+        return passiveAuth;
+    }
+
+    /**
+     * Sets if authentication must be forced.
+     * 
+     * @param forceAuth if the authentication manager must reauth the user.
+     */
+    public void setForceAuth(boolean forceAuth) {
+        this.forceAuth = forceAuth;
+    }
+
+    /**
+     * Sets if authentication must be passive.
+     * 
+     * @param passiveAuth if the authentication manager must not interact with the users UI.
+     */
+    public void setPassiveAuth(boolean passiveAuth) {
+        this.passiveAuth = passiveAuth;
+    }
+
+    /**
+     * Get an optional property object.
+     * 
+     * @param key The key in the properites Map.
+     * 
+     * @return The object, or <code>null</code> is no object exists for the key.
+     */
+    public Object getProperty(String key) {
+        return propsMap.get(key);
+    }
+
+    /**
+     * Sets an optional property object.
+     * 
+     * If an object is already associated with key, it will be overwritten.
+     * 
+     * @param key The key to set.
+     * @param obj The object to associate with key.
+     */
+    public void setProperty(String key, final Serializable obj) {
+        propsMap.put(key, obj);
+    }
+
+    /**
+     * Sets if authentication succeeded.
+     * 
+     * @param authnOK if authentication succeeded;
+     */
+    public void setAuthenticationOK(boolean authnOK) {
+        this.authenticationOK = authnOK;
+    }
+
+    /**
+     * Returns if authentication succeeded.
+     * 
+     * @return <code>true</code> is the user was successfully authenticated.
+     */
+    public boolean getAuthenticationOK() {
+        return authenticationOK;
+    }
+
+    /**
+     * Sets the optional authentication failure message.
+     * 
+     * @param failureMessage A description of why authN failed.
+     */
+    public void setAuthenticationFailureMessage(String failureMessage) {
+        authnFailureMessage = failureMessage;
+    }
+
+    /**
+     * Returns the optional authentication failure message.
+     * 
+     * @return The failure message, or <code>null</code> is none was set.
+     */
+    public String getAuthenticationFailureMessage() {
+        return authnFailureMessage;
+    }
+
+    /**
+     * Set if authentication has been attempted.
+     * 
+     * This method should be called by an {@link AuthenticationHandler} while processing a request.
+     */
+    public void setAuthenticationAttempted() {
+        authnAttempted = true;
+    }
+
+    /**
+     * Returns if authentication has been attempted for this user.
+     * 
+     * @return if authentication has been attempted for this user
+     */
+    public boolean getAuthenticationAttempted() {
+        return authnAttempted;
+    }
+
+    /**
+     * Sets the ID of the authenticated user.
+     * 
+     * @param id The userid.
+     */
+    public void setUserID(String id) {
+        userID = id;
+    }
+
+    /**
+     * Returns the ID of the authenticated user.
+     * 
+     * @return the ID of the user, or <code>null</code> if authentication failed.
+     */
+    public String getUserID() {
+        return userID;
+    }
+
+    /**
+     * Gets the ProfileHandler URL.
+     * 
+     * @return the URL of the profile handler that is invoking the Authentication Manager.
+     */
+    public String getProfileHandlerURL() {
+        return profileHandlerURL;
+    }
+
+    /**
+     * Sets the ProfileHandler URL.
+     * 
+     * @param profileHandlerURL The URL of the profile handler that invoked the AuthenticationManager/
+     */
+    public void setProfileHandlerURL(String profileHandlerURL) {
+        this.profileHandlerURL = profileHandlerURL;
+    }
+
+    /**
+     * Gets the AuthenticationManager URL.
+     * 
+     * @return the URL of the AuthenticationManager.
+     */
+    public String getAuthenticationManagerURL() {
+        return authnManagerURL;
+    }
+
+    /**
+     * Sets the AuthenticationManager's URL.
+     * 
+     * @param authnManagerURL the URL of the AuthenticationManager.
+     */
+    public void setAuthenticationManagerURL(String authnManagerURL) {
+        this.authnManagerURL = authnManagerURL;
+    }
+
+    /**
+     * Gets the authentication instant.
+     * 
+     * @return The instant of authentication, or <code>null</code> if none was set.
+     */
+    public DateTime getAuthenticationInstant() {
+        return authnInstant;
+    }
+
+    /**
+     * Sets the authentication instant.
+     * 
+     * @param authnInstant The instant of authentication.
+     */
+    public void setAuthenticationInstant(final DateTime authnInstant) {
+        this.authnInstant = authnInstant;
+    }
+
+    /**
+     * Gets the duration of authentication.
+     * 
+     * @return The duration of authentication, or zero if none was set.
+     */
+    public long getAuthenticationDuration() {
+        return authnDuration;
+    }
+
+    /**
+     * Sets the duration of authentication.
+     * 
+     * @param authnDuration The duration of authentication.
+     */
+    public void setAuthenticationDuration(long authnDuration) {
+        this.authnDuration = authnDuration;
+    }
+
+    /**
+     * Gets the method used to authenticate the user.
+     * 
+     * @return The method used to authenticate the user.
+     */
+    public String getAuthenticationMethod() {
+        return authnMethod;
+    }
+
+    /**
+     * Sets the method used to authenticate the user.
+     * 
+     * @param authnMethod The method used to authenticate the user.
+     */
+    public void setAuthenticationMethod(String authnMethod) {
+        this.authnMethod = authnMethod;
+    }
+
+    /**
+     * Gets the {@link Session} ID
+     * 
+     * @return the Session id.
+     */
+    public String getSessionID() {
+        return sessionID;
+    }
+
+    /**
+     * Sets the {@link Session} ID
+     * 
+     * @param sessionID the Session ID
+     */
+    public void setSessionID(String sessionID) {
+        this.sessionID = sessionID;
+    }
+
+    /**
+     * Return the acceptable authentication handler URIs for authenticating this user. If no authentication methods are
+     * preferred the resultant list will be empty.
+     * 
+     * @return an array of URIs
+     */
+    public List<String> getRequestedAuthenticationMethods() {
+        return new ArrayList<String>();
+    }
 }
index 945716a..d3bc207 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.authn;
 
+import java.io.Serializable;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.LinkedList;
 
-import org.apache.log4j.Logger;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 
+import org.apache.log4j.Logger;
+import org.opensaml.Configuration;
 import org.opensaml.saml2.core.AuthnContextClassRef;
-import org.opensaml.saml2.core.AuthnContextDeclRef;
 import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.AuthnContextDeclRef;
 import org.opensaml.saml2.core.AuthnRequest;
 import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.util.XMLHelper;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
 
 /**
  * A SAML 2.0 {@link LoginContext}.
  * 
  * This class can interpret {@link RequestedAuthnContext} and act accordingly.
  */
-public class Saml2LoginContext extends LoginContext {
-
-       private static final Logger log = Logger.getLogger(Saml2LoginContext.class);
-
-       /** The {@link RequestedAuthnContext} */
-       private RequestedAuthnContext ctx;
-
-       /**
-        * Creates a new instance of Saml2LoginContext.
-        * 
-        * @param authnRequest
-        *            A SAML 2.0 Authentication Request.
-        */
-       public Saml2LoginContext(AuthnRequest authnRequest) {
-
-               if (authnRequest != null) {
-                       forceAuth = authnRequest.isForceAuthn();
-                       passiveAuth = authnRequest.isPassive();
-                       ctx = authnRequest.getRequestedAuthnContext();
-               }
-       }
-
-       /**
-        * This method evaluates a SAML2 {@link RequestedAuthnContext} and returns
-        * the list of requested authentication method URIs.
-        * 
-        * If the AuthnQuery did not contain a RequestedAuthnContext, this method
-        * will return <code>null</code>.
-        * 
-        * @return An array of authentication method URIs, or <code>null</code>.
-        */
-       public String[] getRequestedAuthenticationMethods() {
-
-               if (ctx == null)
-                       return null;
-
-               // For the immediate future, we only support the "exact" comparator.
-               // XXX: we should probably throw an exception or somehow indicate this
-               // as an error to the caller.
-               AuthnContextComparisonTypeEnumeration comparator = ctx.getComparison();
-               if (comparator != null
-                               && comparator != AuthnContextComparisonTypeEnumeration.EXACT) {
-                       log
-                                       .error("Unsupported comparision operator ( "
-                                                       + comparator
-                                                       + ") in RequestedAuthnContext. Only exact comparisions are supported.");
-                       return null;
-               }
-
-               // build a list of all requested authn classes and declrefs
-               List<String> requestedAuthnMethods = new LinkedList<String>();
-               List<AuthnContextClassRef> authnClasses = ctx
-                               .getAuthnContextClassRefs();
-               List<AuthnContextDeclRef> authnDeclRefs = ctx.getAuthnContextDeclRefs();
-
-               if (authnClasses != null) {
-                       for (AuthnContextClassRef classRef : authnClasses) {
-                               if (classRef != null) {
-                                       String s = classRef.getAuthnContextClassRef();
-                                       if (s != null) {
-                                               requestedAuthnMethods.add(s);
-                                       }
-                               }
-                       }
-               }
-
-               if (authnDeclRefs != null) {
-                       for (AuthnContextDeclRef declRef : authnDeclRefs) {
-                               if (declRef != null) {
-                                       String s = declRef.getAuthnContextDeclRef();
-                                       if (s != null) {
-                                               requestedAuthnMethods.add(s);
-                                       }
-                               }
-                       }
-               }
-
-               if (requestedAuthnMethods.size() == 0) {
-                       return null;
-               } else {
-                       String[] methods = new String[requestedAuthnMethods.size()];
-                       return requestedAuthnMethods.toArray(methods);
-               }
-
-       }
-}
+public class Saml2LoginContext extends LoginContext implements Serializable {
+
+    /** Serial version UID. */
+    private static final long serialVersionUID = -2518779446947534977L;
+
+    /** Class logger. */
+    private final Logger log = Logger.getLogger(Saml2LoginContext.class);
+
+    /** Serialized authentication request. */
+    private String serialAuthnRequest;
+
+    /** Unmarshalled authentication request. */
+    private transient AuthnRequest authnRequest;
+
+    /**
+     * Creates a new instance of Saml2LoginContext.
+     * 
+     * @param relyingParty entity ID of the relying party
+     * @param request SAML 2.0 Authentication Request
+     * 
+     * @throws MarshallingException thrown if the given request can not be marshalled and serialized into a string
+     */
+    public Saml2LoginContext(String relyingParty, AuthnRequest request) throws MarshallingException {
+        if (relyingParty == null || request == null) {
+            throw new IllegalArgumentException("SAML 2 authentication request and relying party ID may not be null");
+        }
+
+        serialAuthnRequest = serializeRequest(request);
+        authnRequest = request;
+        setForceAuth(authnRequest.isForceAuthn());
+        setPassiveAuth(authnRequest.isPassive());
+        setRelyingParty(relyingParty);
+    }
+
+    /**
+     * Gets the authentication request that started the login process.
+     * 
+     * @return authentication request that started the login process
+     * 
+     * @throws UnmarshallingException thrown if the serialized form on the authentication request can be unmarshalled
+     */
+    public AuthnRequest getAuthenticationRequest() throws UnmarshallingException {
+        if (authnRequest == null) {
+            authnRequest = deserializeRequest(serialAuthnRequest);
+        }
+
+        return authnRequest;
+    }
+
+    /**
+     * Gets the requested authentication context information from the authentication request.
+     * 
+     * @return requested authentication context information or null
+     */
+    public RequestedAuthnContext getRequestedAuthenticationContext() {
+        try {
+            AuthnRequest request = getAuthenticationRequest();
+            return request.getRequestedAuthnContext();
+        } catch (UnmarshallingException e) {
+            return null;
+        }
+    }
+
+    /**
+     * This method evaluates a SAML2 {@link RequestedAuthnContext} and returns the list of requested authentication
+     * method URIs.
+     * 
+     * If the AuthnQuery did not contain a RequestedAuthnContext, this method will return <code>null</code>.
+     * 
+     * @return An array of authentication method URIs, or <code>null</code>.
+     */
+    public List<String> getRequestedAuthenticationMethods() {
+        ArrayList<String> requestedMethods = new ArrayList<String>();
+
+        RequestedAuthnContext authnContext = getRequestedAuthenticationContext();
+        if (authnContext == null) {
+            return requestedMethods;
+        }
+
+        // For the immediate future, we only support the "exact" comparator.
+        AuthnContextComparisonTypeEnumeration comparator = authnContext.getComparison();
+        if (comparator != null && comparator != AuthnContextComparisonTypeEnumeration.EXACT) {
+            log.error("Unsupported comparision operator ( " + comparator
+                    + ") in RequestedAuthnContext. Only exact comparisions are supported.");
+            return null;
+        }
+
+        // build a list of all requested authn classes and declrefs
+        List<AuthnContextClassRef> authnClasses = authnContext.getAuthnContextClassRefs();
+        List<AuthnContextDeclRef> authnDeclRefs = authnContext.getAuthnContextDeclRefs();
+
+        if (authnClasses != null) {
+            for (AuthnContextClassRef classRef : authnClasses) {
+                if (classRef != null) {
+                    requestedMethods.add(classRef.getAuthnContextClassRef());
+                }
+            }
+        }
+
+        if (authnDeclRefs != null) {
+            for (AuthnContextDeclRef declRef : authnDeclRefs) {
+                if (declRef != null) {
+                    requestedMethods.add(declRef.getAuthnContextDeclRef());
+                }
+            }
+        }
+
+        return requestedMethods;
+    }
+
+    /**
+     * Serializes an authentication request into a string.
+     * 
+     * @param request the request to serialize
+     * 
+     * @return the serialized form of the string
+     * 
+     * @throws MarshallingException thrown if the request can not be marshalled and serialized
+     */
+    protected String serializeRequest(AuthnRequest request) throws MarshallingException {
+        Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(request);
+        Element requestElem = marshaller.marshall(request);
+        StringWriter writer = new StringWriter();
+        XMLHelper.writeNode(requestElem, writer);
+        return writer.toString();
+    }
+
+    /**
+     * Deserailizes an authentication request from a string.
+     * 
+     * @param request request to deserialize
+     * 
+     * @return the request XMLObject
+     * 
+     * @throws UnmarshallingException thrown if the request can no be deserialized and unmarshalled
+     */
+    protected AuthnRequest deserializeRequest(String request) throws UnmarshallingException {
+        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+        try {
+            DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
+            InputSource requestInput = new InputSource(new StringReader(request));
+            Element requestElem = docBuilder.parse(requestInput).getDocumentElement();
+            Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(requestElem);
+            return (AuthnRequest) unmarshaller.unmarshall(requestElem);
+        } catch (Exception e) {
+            throw new UnmarshallingException("Unable to read serialized authentication request");
+        }
+    }
+
+}
\ No newline at end of file