Remove deserialization work from SAML2 Login context and move it to the SSO profile...
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 29 Oct 2008 09:59:00 +0000 (09:59 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 29 Oct 2008 09:59:00 +0000 (09:59 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/branches/REL_2@2793 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

doc/RELEASE-NOTES.txt
src/main/java/edu/internet2/middleware/shibboleth/idp/authn/Saml2LoginContext.java
src/main/java/edu/internet2/middleware/shibboleth/idp/profile/saml2/AbstractSAML2ProfileHandler.java
src/main/java/edu/internet2/middleware/shibboleth/idp/profile/saml2/SSOProfileHandler.java

index df17554..f1569fe 100644 (file)
@@ -18,6 +18,7 @@ Changes in Release 2.1.0
 [SIDP-197] - Misleading error message for ValidationInfo element in relying-party.xml
 [SIDP-199] - loss of login context when deploying the IdP to tomcat's ROOT context
 [SIDP-201] - IdP sends SAML 1 authentication responses without audience conditions
+[SIDP-202] - Saml2LoginContext unable to deserialize serialized AuthnRequest
 [SIDP-203] - Insufficient information logged to track down errant users
 [SIDP-206] - SessionManagerEntry's back reference to the SessionManager object interferes with clustering
 [SIDP-209] - Enforce SAML 2 metadata SPSSODescriptor/@AuthnRequestsSigned
index 0fa5987..6426f94 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 javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
 import org.opensaml.Configuration;
 import org.opensaml.saml2.core.AuthnContext;
 import org.opensaml.saml2.core.AuthnContextClassRef;
@@ -34,14 +30,12 @@ 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.DatatypeHelper;
 import org.opensaml.xml.util.XMLHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Element;
-import org.xml.sax.InputSource;
 
 /**
  * A SAML 2.0 {@link LoginContext}.
@@ -59,9 +53,6 @@ public class Saml2LoginContext extends LoginContext implements Serializable {
     /** Serialized authentication request. */
     private String serialAuthnRequest;
 
-    /** Unmarshalled authentication request. */
-    private transient AuthnRequest authnRequest;
-
     /**
      * Creates a new instance of Saml2LoginContext.
      * 
@@ -79,27 +70,22 @@ public class Saml2LoginContext extends LoginContext implements Serializable {
         }
         setRelyingParty(relyingParty);
         relayState = state;
-        authnRequest = request;
         serialAuthnRequest = serializeRequest(request);
         
-        setForceAuthRequired(authnRequest.isForceAuthn());
-        setPassiveAuthRequired(authnRequest.isPassive());
-        getRequestedAuthenticationMethods().addAll(extractRequestedAuthenticationMethods());
+        setForceAuthRequired(request.isForceAuthn());
+        setPassiveAuthRequired(request.isPassive());
+        getRequestedAuthenticationMethods().addAll(extractRequestedAuthenticationMethods(request));
     }
 
     /**
-     * Gets the authentication request that started the login process.
+     * Gets the serialized 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 synchronized AuthnRequest getAuthenticationRequest() throws UnmarshallingException {
-        if (authnRequest == null) {
-            authnRequest = deserializeRequest(serialAuthnRequest);
-        }
-
-        return authnRequest;
+    public synchronized String getAuthenticationRequest() throws UnmarshallingException {
+        return serialAuthnRequest;
     }
     
     /**
@@ -112,20 +98,6 @@ public class Saml2LoginContext extends LoginContext implements Serializable {
     }
 
     /**
-     * Gets the requested authentication context information from the authentication request.
-     * 
-     * @return requested authentication context information or null
-     */
-    public synchronized RequestedAuthnContext getRequestedAuthenticationContext() {
-        try {
-            AuthnRequest request = getAuthenticationRequest();
-            return request.getRequestedAuthnContext();
-        } catch (UnmarshallingException e) {
-            return null;
-        }
-    }
-
-    /**
      * Serializes an authentication request into a string.
      * 
      * @param request the request to serialize
@@ -142,37 +114,18 @@ public class Saml2LoginContext extends LoginContext implements Serializable {
         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");
-        }
-    }
     
     /**
      * Extracts the authentication methods requested within the request.
      * 
+     * @param request the authentication request
+     * 
      * @return requested authentication methods, or an empty list if no preference
      */
-    protected List<String> extractRequestedAuthenticationMethods(){
+    protected List<String> extractRequestedAuthenticationMethods(AuthnRequest request){
         ArrayList<String> requestedMethods = new ArrayList<String>();
 
-        RequestedAuthnContext authnContext = getRequestedAuthenticationContext();
+        RequestedAuthnContext authnContext = request.getRequestedAuthnContext();
         if (authnContext == null) {
             return requestedMethods;
         }
index a2b35a5..4f97a9e 100644 (file)
@@ -132,7 +132,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
     /** For building audience restriction. */
     private SAMLObjectBuilder<AudienceRestriction> audienceRestrictionBuilder;
 
-    /** For building proxy retrictions. */
+    /** For building proxy restrictions. */
     private SAMLObjectBuilder<ProxyRestriction> proxyRestrictionBuilder;
 
     /** For building audience. */
index 84bd585..dc3dd17 100644 (file)
 package edu.internet2.middleware.shibboleth.idp.profile.saml2;
 
 import java.io.IOException;
+import java.io.StringReader;
 import java.util.ArrayList;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
+import org.opensaml.Configuration;
 import org.opensaml.common.SAMLObjectBuilder;
 import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
 import org.opensaml.common.xml.SAMLConstants;
@@ -52,11 +56,14 @@ import org.opensaml.ws.transport.http.HTTPOutTransport;
 import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
 import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
 import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.io.Unmarshaller;
 import org.opensaml.xml.io.UnmarshallingException;
 import org.opensaml.xml.security.SecurityException;
 import org.opensaml.xml.util.DatatypeHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
 
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
 import edu.internet2.middleware.shibboleth.common.profile.provider.BaseSAMLProfileRequestContext;
@@ -396,10 +403,10 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             Saml2LoginContext loginContext = ssoRequestContext.getLoginContext();
             requestContext.setRelayState(loginContext.getRelayState());
 
-            AuthnRequest authnRequest = loginContext.getAuthenticationRequest();
+            AuthnRequest authnRequest = deserializeRequest(loginContext.getAuthenticationRequest());
             requestContext.setInboundMessage(authnRequest);
-            requestContext.setInboundSAMLMessage(loginContext.getAuthenticationRequest());
-            requestContext.setInboundSAMLMessageId(loginContext.getAuthenticationRequest().getID());
+            requestContext.setInboundSAMLMessage(authnRequest);
+            requestContext.setInboundSAMLMessageId(authnRequest.getID());
 
             Subject authnSubject = authnRequest.getSubject();
             if (authnSubject != null) {
@@ -539,6 +546,26 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
 
         return endpoint;
     }
+    
+
+    /**
+     * 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 {
+        try {
+            Element requestElem = getParserPool().parse(new StringReader(request)).getDocumentElement();
+            Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(requestElem);
+            return (AuthnRequest) unmarshaller.unmarshall(requestElem);
+        } catch (Exception e) {
+            throw new UnmarshallingException("Unable to read serialized authentication request");
+        }
+    }
 
     /** Represents the internal state of a SAML 2.0 SSO Request while it's being processed by the IdP. */
     protected class SSORequestContext extends BaseSAML2ProfileRequestContext<AuthnRequest, Response, SSOConfiguration> {