Extract information from decoders and store in requests context instead of store...
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 12 Jul 2007 09:59:46 +0000 (09:59 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 12 Jul 2007 09:59:46 +0000 (09:59 +0000)
  - fix bug with lost relay state on SAML 2 SSO
  - allows possibly large object graph to be garbage collected sooner

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

src/edu/internet2/middleware/shibboleth/idp/authn/Saml2LoginContext.java
src/edu/internet2/middleware/shibboleth/idp/profile/AbstractSAMLProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/AbstractSAML1ProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/AttributeQueryProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSOProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/AbstractSAML2ProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/AttributeQueryProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/SSOProfileHandler.java
test/edu/internet2/middleware/shibboleth/idp/system/conf1/SAML2SSOTestCase.java

index b6aaa73..3a10c08 100644 (file)
@@ -52,6 +52,9 @@ public class Saml2LoginContext extends LoginContext implements Serializable {
 
     /** Class logger. */
     private final Logger log = Logger.getLogger(Saml2LoginContext.class);
+    
+    /** Relay state from authentication request. */
+    private String relayState;
 
     /** Serialized authentication request. */
     private String serialAuthnRequest;
@@ -63,17 +66,19 @@ public class Saml2LoginContext extends LoginContext implements Serializable {
      * Creates a new instance of Saml2LoginContext.
      * 
      * @param relyingParty entity ID of the relying party
+     * @param state relay state from incoming authentication request
      * @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 {
+    public Saml2LoginContext(String relyingParty, String state, AuthnRequest request) throws MarshallingException {
         super();
         
         if (relyingParty == null || request == null) {
             throw new IllegalArgumentException("SAML 2 authentication request and relying party ID may not be null");
         }
         setRelyingParty(relyingParty);
+        relayState = state;
         authnRequest = request;
         serialAuthnRequest = serializeRequest(request);
         
@@ -96,6 +101,15 @@ public class Saml2LoginContext extends LoginContext implements Serializable {
 
         return authnRequest;
     }
+    
+    /**
+     * Gets the relay state from the orginating authentication request.
+     * 
+     * @return relay state from the orginating authentication request
+     */
+    public String getRelayState(){
+        return relayState;
+    }
 
     /**
      * Gets the requested authentication context information from the authentication request.
index 643cbf7..0551e46 100644 (file)
@@ -165,6 +165,15 @@ public abstract class AbstractSAMLProfileHandler extends
 
         /** Role descriptor meatadata for the asserting party. */
         private RoleDescriptor assertingPartyRoleMetadata;
+        
+        /** Message decoder URI. */
+        private String messageDecoder;
+        
+        /** Message encoder URI. */
+        private String messageEncoder;
+        
+        /** Request relay state. */
+        private String relayState;
 
         /** Endpoint of relying party. */
         private Endpoint relyingPartyEndpoint;
@@ -223,6 +232,60 @@ public abstract class AbstractSAMLProfileHandler extends
         }
         
         /**
+         * Gets the URI of the message decoder used to decode the incoming request.
+         * 
+         * @return URI of the message decoder used to decode the incoming request
+         */
+        public String getMessageDecoder(){
+            return messageDecoder;
+        }
+        
+        /**
+         * Sets the URI of the message decoder used to decode the incoming request.
+         * 
+         * @param decoderURI URI of the message decoder used to decode the incoming request
+         */
+        public void setMessageDecoder(String decoderURI){
+            messageDecoder = decoderURI;
+        }
+        
+        /**
+         * Gets the URI of the message encoder used to encode the outgoing response.
+         * 
+         * @return URI of the message encoder used to encode the outgoing response
+         */
+        public String getMessageEncoder(){
+            return messageEncoder;
+        }
+        
+        /**
+         * Sets the URI of the message encoder used to encode the outgoing response.
+         * 
+         * @param encoderURI URI of the message encoder used to encode the outgoing response
+         */
+        public void setMessageEncoder(String encoderURI){
+            messageEncoder = encoderURI;
+        }
+        
+        /**
+         * Gets the relay state of the current request.
+         * 
+         * @return relay state of the current request
+         */
+        public String getRelayState(){
+            return relayState;
+        }
+        
+        /**
+         * Sets the relay state of the current request.
+         * 
+         * @param state relay state of the current request
+         */
+        public void setRelayState(String state){
+            
+        }
+        
+        /**
          * Gets the endpoint for the relying party.
          * 
          * @return endpoint for the relying party
index 9266f31..f763743 100644 (file)
@@ -706,11 +706,9 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
         auditLogEntry.setPrincipalName(context.getPrincipalName());
         auditLogEntry.setAssertingPartyId(context.getAssertingPartyId());
         auditLogEntry.setRelyingPartyId(context.getRelyingPartyId());
-        if (context.getMessageDecoder() != null) {
-            auditLogEntry.setRequestBinding(context.getMessageDecoder().getBindingURI());
-        }
+        auditLogEntry.setRequestBinding(context.getMessageDecoder());
         auditLogEntry.setRequestId(null);
-        auditLogEntry.setResponseBinding(context.getMessageEncoder().getBindingURI());
+        auditLogEntry.setResponseBinding(context.getMessageEncoder());
         auditLogEntry.setResponseId(context.getSamlResponse().getID());
         if (context.getPrincipalAttributes() != null) {
             auditLogEntry.getReleasedAttributes().addAll(context.getPrincipalAttributes().keySet());
index 7c882ee..36c5ec4 100644 (file)
@@ -112,7 +112,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
 
         ProfileRequest<ServletRequest> profileRequest = requestContext.getProfileRequest();
         decoder.setRequest(profileRequest.getRawRequest());
-        requestContext.setMessageDecoder(decoder);
+        requestContext.setMessageDecoder(decoder.getBindingURI());
 
         try {
             decoder.decode();
@@ -130,10 +130,10 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
             throw new ProfileException("Message did not meet security policy requirements", e);
         } finally {
             // Set as much information as can be retrieved from the decoded message
-            SAMLSecurityPolicy securityPolicy = requestContext.getMessageDecoder().getSecurityPolicy();
+            SAMLSecurityPolicy securityPolicy = decoder.getSecurityPolicy();
             requestContext.setRelyingPartyId(securityPolicy.getIssuer());
 
-            Request request = (Request) requestContext.getMessageDecoder().getSAMLMessage();
+            Request request = (Request) decoder.getSAMLMessage();
             requestContext.setSamlRequest(request);
             requestContext.setAttributeQuery(request.getAttributeQuery());
 
@@ -237,11 +237,11 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
         }
 
         super.populateMessageEncoder(encoder);
-        encoder.setRelayState(requestContext.getMessageDecoder().getRelayState());
+        encoder.setRelayState(requestContext.getRelayState());
         ProfileResponse<ServletResponse> profileResponse = requestContext.getProfileResponse();
         encoder.setResponse(profileResponse.getRawResponse());
         encoder.setSamlMessage(requestContext.getSamlResponse());
-        requestContext.setMessageEncoder(encoder);
+        requestContext.setMessageEncoder(encoder.getBindingURI());
 
         try {
             encoder.encode();
index 1ca0236..c2758e5 100644 (file)
@@ -281,6 +281,8 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
             ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response) throws ProfileException {
         ShibbolethSSORequestContext requestContext = new ShibbolethSSORequestContext(request, response);
 
+        requestContext.setRelayState(loginContext.getSpTarget());
+        
         requestContext.setLoginContext(loginContext);
 
         requestContext.setPrincipalName(loginContext.getPrincipalName());
@@ -444,11 +446,11 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
                 relyingPartyEndpoint.getBinding());
         encoder.setRelyingPartyEndpoint(relyingPartyEndpoint);
         super.populateMessageEncoder(encoder);
-        encoder.setRelayState(requestContext.getLoginContext().getSpTarget());
+        encoder.setRelayState(requestContext.getRelayState());
         ProfileResponse<ServletResponse> profileResponse = requestContext.getProfileResponse();
         encoder.setResponse(profileResponse.getRawResponse());
         encoder.setSamlMessage(requestContext.getSamlResponse());
-        requestContext.setMessageEncoder(encoder);
+        requestContext.setMessageEncoder(encoder.getBindingURI());
 
         try {
             encoder.encode();
index 7f4b7bf..7eceb9d 100644 (file)
@@ -770,9 +770,9 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
         auditLogEntry.setPrincipalName(context.getPrincipalName());
         auditLogEntry.setAssertingPartyId(context.getAssertingPartyId());
         auditLogEntry.setRelyingPartyId(context.getRelyingPartyId());
-        auditLogEntry.setRequestBinding(context.getMessageDecoder().getBindingURI());
+        auditLogEntry.setRequestBinding(context.getMessageDecoder());
         auditLogEntry.setRequestId(context.getSamlRequest().getID());
-        auditLogEntry.setResponseBinding(context.getMessageEncoder().getBindingURI());
+        auditLogEntry.setResponseBinding(context.getMessageEncoder());
         auditLogEntry.setResponseId(context.getSamlResponse().getID());
         if (context.getPrincipalAttributes() != null) {
             auditLogEntry.getReleasedAttributes().addAll(context.getPrincipalAttributes().keySet());
index 38318ad..f214e89 100644 (file)
@@ -118,7 +118,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
 
         ProfileRequest<ServletRequest> profileRequest = requestContext.getProfileRequest(); 
         decoder.setRequest(profileRequest.getRawRequest());
-        requestContext.setMessageDecoder(decoder);
+        requestContext.setMessageDecoder(decoder.getBindingURI());
 
         try {
             decoder.decode();
@@ -136,7 +136,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
             throw new ProfileException("Message did not meet security policy requirements", e);
         } finally {
             // Set as much information as can be retrieved from the decoded message
-            SAMLSecurityPolicy securityPolicy = requestContext.getMessageDecoder().getSecurityPolicy();
+            SAMLSecurityPolicy securityPolicy = decoder.getSecurityPolicy();
             requestContext.setRelyingPartyId(securityPolicy.getIssuer());
 
             try {
@@ -160,7 +160,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
                 requestContext.setProfileConfiguration((AttributeQueryConfiguration) rpConfig
                         .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID));
 
-                requestContext.setSamlRequest((AttributeQuery) requestContext.getMessageDecoder().getSAMLMessage());
+                requestContext.setSamlRequest((AttributeQuery) decoder.getSAMLMessage());
             } catch (MetadataProviderException e) {
                 log.error("Unable to locate metadata for asserting or relying party");
                 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, null,
@@ -188,11 +188,11 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
         }
 
         super.populateMessageEncoder(encoder);
-        encoder.setRelayState(requestContext.getMessageDecoder().getRelayState());
+        encoder.setRelayState(requestContext.getRelayState());
         ProfileResponse<ServletResponse> profileResponse = requestContext.getProfileResponse();
         encoder.setResponse(profileResponse.getRawResponse());
         encoder.setSamlMessage(requestContext.getSamlResponse());
-        requestContext.setMessageEncoder(encoder);
+        requestContext.setMessageEncoder(encoder.getBindingURI());
 
         try {
             encoder.encode();
index 3dfaa90..675b761 100644 (file)
@@ -171,7 +171,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
 
             authnRequest = (AuthnRequest) decoder.getSAMLMessage();
 
-            Saml2LoginContext loginContext = new Saml2LoginContext(relyingParty, authnRequest);
+            Saml2LoginContext loginContext = new Saml2LoginContext(relyingParty, decoder.getRelayState(), authnRequest);
             loginContext.setAuthenticationEngineURL(authenticationManagerPath);
             loginContext.setProfileHandlerURL(HttpHelper.getRequestUriWithoutContext(httpRequest));
             if (loginContext.getRequestedAuthenticationMethods().size() == 0) {
@@ -294,7 +294,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         SSORequestContext requestContext = new SSORequestContext(request, response);
 
         try {
-            requestContext.setMessageDecoder(getMessageDecoderFactory().getMessageDecoder(decodingBinding));
+            requestContext.setMessageDecoder(decodingBinding);
 
             requestContext.setLoginContext(loginContext);
 
@@ -468,14 +468,14 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
 
         super.populateMessageEncoder(encoder);
         encoder.setIssuer(requestContext.getAssertingPartyId());
-        encoder.setRelayState(requestContext.getMessageDecoder().getRelayState());
+        encoder.setRelayState(requestContext.getRelayState());
         encoder.setRelyingParty(requestContext.getRelyingPartyMetadata());
         encoder.setRelyingPartyEndpoint(relyingPartyEndpoint);
         encoder.setRelyingPartyRole(requestContext.getRelyingPartyRoleMetadata());
         ProfileResponse<ServletResponse> profileResponse = requestContext.getProfileResponse();
         encoder.setResponse(profileResponse.getRawResponse());
         encoder.setSamlMessage(requestContext.getSamlResponse());
-        requestContext.setMessageEncoder(encoder);
+        requestContext.setMessageEncoder(encoder.getBindingURI());
 
         try {
             encoder.encode();
index 695f7ae..bb447fe 100644 (file)
@@ -102,7 +102,7 @@ public class SAML2SSOTestCase extends BaseConf1TestCase {
     public void testSecondLeg() throws Exception {
         AuthnRequest authnRequest = buildAuthnRequest("urn:example.org:unitTestFed:sp2");
         
-        Saml2LoginContext loginContext = new Saml2LoginContext("urn:example.org:unitTestFed:sp2", authnRequest);
+        Saml2LoginContext loginContext = new Saml2LoginContext("urn:example.org:unitTestFed:sp2", null, authnRequest);
         loginContext.setAuthenticationInstant(new DateTime());
         loginContext.setAuthenticationMethod("urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified");
         loginContext.setPrincipalAuthenticated(true);