Mostly synched with OpenSAML changes
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Mon, 13 Aug 2007 12:37:14 +0000 (12:37 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Mon, 13 Aug 2007 12:37:14 +0000 (12:37 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2329 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

17 files changed:
src/edu/internet2/middleware/shibboleth/idp/profile/AbstractSAMLProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/IdPProfileHandlerManager.java
src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileRequest.java [deleted file]
src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileRequestDispatcher.java [deleted file]
src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileResponse.java [deleted file]
src/edu/internet2/middleware/shibboleth/idp/profile/StatusProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/AbstractSAML1ProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ArtifactQuery.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/AttributeQueryProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/BaseSAML1ProfileRequestContext.java [new file with mode: 0644]
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/ArtifactResolution.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/AttributeQueryProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/BaseSAML2ProfileRequestContext.java [new file with mode: 0644]
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/LogoutRequest.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/SSOProfileHandler.java

index f749daa..709a5e3 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.profile;
 
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.log4j.Logger;
 import org.opensaml.common.IdentifierGenerator;
-import org.opensaml.common.SAMLObject;
-import org.opensaml.common.binding.decoding.MessageDecoderFactory;
-import org.opensaml.common.binding.encoding.MessageEncoderFactory;
-import org.opensaml.saml2.metadata.Endpoint;
-import org.opensaml.saml2.metadata.EntityDescriptor;
-import org.opensaml.saml2.metadata.RoleDescriptor;
+import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
+import org.opensaml.common.binding.encoding.SAMLMessageEncoder;
 import org.opensaml.saml2.metadata.provider.MetadataProvider;
+import org.opensaml.ws.transport.InTransport;
+import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
 
 import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.profile.provider.AbstractShibbolethProfileHandler;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.SAMLMDRelyingPartyConfigurationManager;
 import edu.internet2.middleware.shibboleth.idp.session.Session;
@@ -49,11 +43,11 @@ public abstract class AbstractSAMLProfileHandler extends
     /** Generator of IDs which may be used for SAML assertions, requests, etc. */
     private IdentifierGenerator idGenerator;
 
-    /** Factory of message decoders. */
-    private MessageDecoderFactory decoderFactory;
+    /** Decoder used to extract message information from the inbound transport. */
+    private SAMLMessageDecoder messageDecoder;
 
-    /** Factory of message encoders. */
-    private MessageEncoderFactory encoderFactory;
+    /** Encoder used to bind information to the outbound message transport. */
+    private SAMLMessageEncoder messageEncoder;
 
     /** Constructor. */
     protected AbstractSAMLProfileHandler() {
@@ -61,57 +55,39 @@ public abstract class AbstractSAMLProfileHandler extends
     }
 
     /**
-     * Gets an ID generator which may be used for SAML assertions, requests, etc.
+     * Gets the audit log for this handler.
      * 
-     * @return ID generator
+     * @return audit log for this handler
      */
-    public IdentifierGenerator getIdGenerator() {
-        return idGenerator;
+    protected Logger getAduitLog() {
+        return auditLog;
     }
 
     /**
      * Gets an ID generator which may be used for SAML assertions, requests, etc.
      * 
-     * @param generator an ID generator which may be used for SAML assertions, requests, etc
-     */
-    public void setIdGenerator(IdentifierGenerator generator) {
-        idGenerator = generator;
-    }
-
-    /**
-     * Gets the factory used to build new message decoders.
-     * 
-     * @return factory used to build new message decoders
-     */
-    public MessageDecoderFactory getMessageDecoderFactory() {
-        return decoderFactory;
-    }
-
-    /**
-     * Sets the factory used to build new message decoders.
-     * 
-     * @param factory factory used to build new message decoders
+     * @return ID generator
      */
-    public void setMessageDecoderFactory(MessageDecoderFactory factory) {
-        decoderFactory = factory;
+    public IdentifierGenerator getIdGenerator() {
+        return idGenerator;
     }
 
     /**
-     * Gets the factory used to build message encoders.
+     * Gets the decoder used to extract message information from the inbound transport.
      * 
-     * @return factory used to build message encoders
+     * @return decoder used to extract message information from the inbound transport
      */
-    public MessageEncoderFactory getMessageEncoderFactory() {
-        return encoderFactory;
+    public SAMLMessageDecoder getMessageDecoder() {
+        return messageDecoder;
     }
 
     /**
-     * Sets the factory used to build message encoders.
+     * Gets the encoder used to bind information to the outbound message transport.
      * 
-     * @param factory factory used to build message encoders
+     * @return encoder used to bind information to the outbound message transport
      */
-    public void setMessageEncoderFactory(MessageEncoderFactory factory) {
-        encoderFactory = factory;
+    public SAMLMessageEncoder getMessageEncoder() {
+        return messageEncoder;
     }
 
     /**
@@ -129,214 +105,58 @@ public abstract class AbstractSAMLProfileHandler extends
     }
 
     /**
-     * Gets the audit log for this handler.
-     * 
-     * @return audit log for this handler
-     */
-    protected Logger getAduitLog() {
-        return auditLog;
-    }
-
-    /**
      * Gets the user's session ID from the current request.
      * 
-     * @param request current request
+     * @param inTransport current inbound transport
      * 
      * @return user's session ID
      */
-    protected String getUserSessionId(ProfileRequest<ServletRequest> request) {
-        HttpServletRequest rawRequest = (HttpServletRequest) request.getRawRequest();
+    protected String getUserSessionId(InTransport inTransport) {
+        HttpServletRequest rawRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
+
         if (rawRequest != null) {
             return (String) rawRequest.getSession().getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
         }
 
         return null;
     }
-
+    
     /**
-     * Contextual object used to accumlate information as profile requests are being processed.
+     * Gets the user's session, if there is one.
      * 
-     * @param <StatusType> type of Status object
+     * @param inTransport current inbound transport
+     * 
+     * @return user's session
      */
-    protected class SAMLProfileRequestContext<StatusType extends SAMLObject> extends ShibbolethProfileRequestContext {
-        
-        /** Entity descriptor for the asserting party. */
-        private EntityDescriptor assertingPartyMetadata;
-
-        /** 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;
-        
-        /** Entity descriptor for the relying party. */
-        private EntityDescriptor relyingPartyMetadata;
-
-        /** Role descriptor meatadata for the relying party. */
-        private RoleDescriptor relyingPartyRoleMetadata;
-
-        /**
-         * Constructor.
-         * 
-         * @param request current profile request
-         * @param response current profile response
-         */
-        public SAMLProfileRequestContext(ProfileRequest<ServletRequest> request,
-                ProfileResponse<ServletResponse> response) {
-            super(request, response);
-        }
-
-        /**
-         * Gets the metadata for the asserting party.
-         * 
-         * @return metadata for the asserting party
-         */
-        public EntityDescriptor getAssertingPartyMetadata() {
-            return assertingPartyMetadata;
-        }
-
-        /**
-         * Sets the metadata for the asserting party.
-         * 
-         * @param metadata metadata for the asserting party
-         */
-        public void setAssertingPartyMetadata(EntityDescriptor metadata) {
-            assertingPartyMetadata = metadata;
-        }
-
-        /**
-         * Gets the role descriptor for the asserting party.
-         * 
-         * @return role descriptor for the asserting party
-         */
-        public RoleDescriptor getAssertingPartyRoleMetadata() {
-            return assertingPartyRoleMetadata;
-        }
-
-        /**
-         * Sets the role descriptor for the asserting party.
-         * 
-         * @param descriptor role descriptor for the asserting party
-         */
-        public void setAssertingPartyRoleMetadata(RoleDescriptor descriptor) {
-            assertingPartyRoleMetadata = descriptor;
-        }
-        
-        /**
-         * 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){
-            relayState = state;
-        }
-        
-        /**
-         * Gets the endpoint for the relying party.
-         * 
-         * @return endpoint for the relying party
-         */
-        public Endpoint getRelyingPartyEndpoint(){
-            return relyingPartyEndpoint;
-        }
-        
-        /**
-         * Sets the endpoint for the relying party.
-         * 
-         * @param endpoint endpoint for the relying party
-         */
-        public void setRelyingPartyEndpoint(Endpoint endpoint){
-            relyingPartyEndpoint = endpoint;
-        }
-
-        /**
-         * Gets the metadata for the relying party.
-         * 
-         * @return metadata for the relying party
-         */
-        public EntityDescriptor getRelyingPartyMetadata() {
-            return relyingPartyMetadata;
-        }
+    protected Session getUserSession(InTransport inTransport){
+        String sessionId = getUserSessionId(inTransport);
+        return getSessionManager().getSession(sessionId);
+    }
 
-        /**
-         * Sets the metadata for the relying party.
-         * 
-         * @param metadata metadata for the relying party
-         */
-        public void setRelyingPartyMetadata(EntityDescriptor metadata) {
-            relyingPartyMetadata = metadata;
-        }
+    /**
+     * Gets an ID generator which may be used for SAML assertions, requests, etc.
+     * 
+     * @param generator an ID generator which may be used for SAML assertions, requests, etc
+     */
+    public void setIdGenerator(IdentifierGenerator generator) {
+        idGenerator = generator;
+    }
 
-        /**
-         * Gets the role descriptor for the relying party.
-         * 
-         * @return role descriptor for the relying party
-         */
-        public RoleDescriptor getRelyingPartyRoleMetadata() {
-            return relyingPartyRoleMetadata;
-        }
+    /**
+     * Sets the decoder used to extract message information from the inbound transport.
+     * 
+     * @param decoder decoder used to extract message information from the inbound transport
+     */
+    public void setMessageDecoder(SAMLMessageDecoder decoder) {
+        messageDecoder = decoder;
+    }
 
-        /**
-         * Sets the role descriptor for the relying party.
-         * 
-         * @param descriptor role descriptor for the relying party
-         */
-        public void setRelyingPartyRoleMetadata(RoleDescriptor descriptor) {
-            relyingPartyRoleMetadata = descriptor;
-        }
+    /**
+     * Sets the encoder used to bind information to the outbound message transport.
+     * 
+     * @param encoder encoder used to bind information to the outbound message transport
+     */
+    public void setMessageEncoder(SAMLMessageEncoder encoder) {
+        messageEncoder = encoder;
     }
 }
\ No newline at end of file
index 6ba910d..6006fc6 100644 (file)
@@ -237,7 +237,7 @@ public class IdPProfileHandlerManager extends BaseReloadableService implements P
         }
 
         profileHandlers.clear();
-        AbstractRequestURIMappedProfileHandler profileHandler;
+        AbstractRequestURIMappedProfileHandler<?,?> profileHandler;
         for (String profileBeanName : profileBeanNames) {
             profileHandler = (AbstractRequestURIMappedProfileHandler) newServiceContext.getBean(profileBeanName);
             for (String requestPath : profileHandler.getRequestPaths()) {
diff --git a/src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileRequest.java b/src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileRequest.java
deleted file mode 100644 (file)
index 789c1aa..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.idp.profile;
-
-import javax.servlet.http.HttpServletRequest;
-
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-
-/**
- * Shibboleth {@link ProfileRequest}.
- */
-public class ShibbolethProfileRequest implements ProfileRequest<HttpServletRequest> {
-
-    /** The in comming request. */
-    private HttpServletRequest rawRequest;
-
-    /**
-     * Constructor.
-     * 
-     * @param request the incomming HTTP request
-     */
-    public ShibbolethProfileRequest(HttpServletRequest request){
-        rawRequest = request;
-    }
-
-    /** {@inheritDoc} */
-    public HttpServletRequest getRawRequest() {
-        return rawRequest;
-    }
-}
\ No newline at end of file
diff --git a/src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileRequestDispatcher.java b/src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileRequestDispatcher.java
deleted file mode 100644 (file)
index b3e5aa3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright [2006] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.idp.profile;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import edu.internet2.middleware.shibboleth.common.profile.BaseServletProfileRequestDispatcher;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
-
-/**
- * Servlet responsible for dispatching incoming shibboleth requests to the appropriate profile handler.
- */
-public class ShibbolethProfileRequestDispatcher extends BaseServletProfileRequestDispatcher {
-
-    /** Serial version UID. */
-    private static final long serialVersionUID = -3939942569721369334L;
-
-    /** {@inheritDoc} */
-    protected ProfileRequest getProfileRequest(ServletRequest request) {
-        return new ShibbolethProfileRequest((HttpServletRequest) request);
-    }
-
-    /** {@inheritDoc} */
-    protected ProfileResponse getProfileResponse(ServletResponse response) {
-        return new ShibbolethProfileResponse((HttpServletResponse) response);
-    }
-}
\ No newline at end of file
diff --git a/src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileResponse.java b/src/edu/internet2/middleware/shibboleth/idp/profile/ShibbolethProfileResponse.java
deleted file mode 100644 (file)
index db6be4d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.idp.profile;
-
-import javax.servlet.http.HttpServletResponse;
-
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
-
-/**
- * Shibboleth {@link ProfileResponse}.
- */
-public class ShibbolethProfileResponse implements ProfileResponse<HttpServletResponse> {
-
-    /** The outgoing response. */
-    private HttpServletResponse rawResponse;
-
-    /**
-     * Constructor.
-     * 
-     * @param response the raw response
-
-     */
-    public ShibbolethProfileResponse(HttpServletResponse response) {
-        rawResponse = response;
-    }
-
-    /** {@inheritDoc} */
-    public HttpServletResponse getRawResponse() {
-        return rawResponse;
-    }
-}
\ No newline at end of file
index 7865802..d39ca9a 100644 (file)
 package edu.internet2.middleware.shibboleth.idp.profile;
 
 import java.io.IOException;
-import java.io.PrintWriter;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
+import java.io.OutputStreamWriter;
 
 import org.apache.log4j.Logger;
+import org.opensaml.ws.transport.InTransport;
+import org.opensaml.ws.transport.OutTransport;
 
-import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.profile.provider.AbstractRequestURIMappedProfileHandler;
 
 /**
@@ -44,11 +40,10 @@ public class StatusProfileHandler extends AbstractRequestURIMappedProfileHandler
     }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
-            throws ProfileException {
+    public void processRequest(InTransport in, OutTransport out) {
         try {
-            PrintWriter out = response.getRawResponse().getWriter();
-            out.write("ok");
+            OutputStreamWriter writer = new OutputStreamWriter(out.getOutgoingStream());
+            writer.write("ok");
         } catch (IOException e) {
             log.error("Unable to write response", e);
         }
index f763743..e2c7226 100644 (file)
@@ -21,8 +21,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.xml.namespace.QName;
 
 import org.apache.log4j.Logger;
@@ -71,8 +69,6 @@ import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML1Attrib
 import edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAMLAttributeRequestContext;
 import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.AbstractSAML1ProfileConfiguration;
 import edu.internet2.middleware.shibboleth.idp.profile.AbstractSAMLProfileHandler;
 import edu.internet2.middleware.shibboleth.idp.session.ServiceInformation;
@@ -157,8 +153,8 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if the major version of the SAML request is not 1
      */
-    protected void checkSamlVersion(SAML1ProfileRequestContext requestContext) throws ProfileException {
-        SAMLObject samlObject = requestContext.getSamlRequest();
+    protected void checkSamlVersion(BaseSAML1ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
+        SAMLObject samlObject = requestContext.getInboundSAMLMessage();
 
         if (samlObject instanceof RequestAbstractType) {
             RequestAbstractType request = (RequestAbstractType) samlObject;
@@ -184,7 +180,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if there is a problem creating the SAML response
      */
-    protected Response buildResponse(SAML1ProfileRequestContext requestContext, List<Statement> statements)
+    protected Response buildResponse(BaseSAML1ProfileRequestContext<?,?,?> requestContext, List<Statement> statements)
             throws ProfileException {
 
         DateTime issueInstant = new DateTime();
@@ -219,12 +215,12 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @return the built assertion
      */
-    protected Assertion buildAssertion(SAML1ProfileRequestContext requestContext, DateTime issueInstant) {
+    protected Assertion buildAssertion(BaseSAML1ProfileRequestContext<?,?,?> requestContext, DateTime issueInstant) {
         Assertion assertion = assertionBuilder.buildObject();
         assertion.setID(getIdGenerator().generateIdentifier());
         assertion.setIssueInstant(issueInstant);
         assertion.setVersion(SAMLVersion.VERSION_11);
-        assertion.setIssuer(requestContext.getAssertingPartyId());
+        assertion.setIssuer(requestContext.getAssertingPartyEntityId());
 
         Conditions conditions = buildConditions(requestContext, issueInstant);
         assertion.setConditions(conditions);
@@ -241,7 +237,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @return constructed conditions
      */
-    protected Conditions buildConditions(SAML1ProfileRequestContext requestContext, DateTime issueInstant) {
+    protected Conditions buildConditions(BaseSAML1ProfileRequestContext<?,?,?> requestContext, DateTime issueInstant) {
         AbstractSAML1ProfileConfiguration profileConfig = requestContext.getProfileConfiguration();
 
         Conditions conditions = conditionsBuilder.buildObject();
@@ -276,7 +272,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * @throws ProfileException thrown if a NameID can not be created either because there was a problem encoding the
      *             name ID attribute or because there are no supported name formats
      */
-    protected Subject buildSubject(SAML1ProfileRequestContext requestContext, String confirmationMethod)
+    protected Subject buildSubject(BaseSAML1ProfileRequestContext<?,?,?> requestContext, String confirmationMethod)
             throws ProfileException {
         NameIdentifier nameID = buildNameId(requestContext);
         requestContext.setSubjectNameID(nameID);
@@ -308,9 +304,9 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * @throws ProfileException thrown if a NameIdentifier can not be created either because there was a problem
      *             encoding the name ID attribute or because there are no supported name formats
      */
-    protected NameIdentifier buildNameId(SAML1ProfileRequestContext requestContext) throws ProfileException {
+    protected NameIdentifier buildNameId(BaseSAML1ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Building assertion NameIdentifier to relying party " + requestContext.getRelyingPartyId()
+            log.debug("Building assertion NameIdentifier to relying party " + requestContext.getRelyingPartyEntityId()
                     + " for principal " + requestContext.getPrincipalName());
         }
         Map<String, BaseAttribute> principalAttributes = requestContext.getPrincipalAttributes();
@@ -368,7 +364,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if there is a problem determing the NameIdentifier format to use
      */
-    protected List<String> getNameFormats(SAML1ProfileRequestContext requestContext) throws ProfileException {
+    protected List<String> getNameFormats(BaseSAML1ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
         ArrayList<String> nameFormats = new ArrayList<String>();
 
         RoleDescriptor assertingPartyRole = requestContext.getAssertingPartyRoleMetadata();
@@ -425,7 +421,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @return the constructed error response
      */
-    protected Response buildErrorResponse(SAML1ProfileRequestContext requestContext) {
+    protected Response buildErrorResponse(BaseSAML1ProfileRequestContext<?,?,?> requestContext) {
         Response samlResponse = responseBuilder.buildObject();
         samlResponse.setIssueInstant(new DateTime());
         populateStatusResponse(requestContext, samlResponse);
@@ -441,10 +437,10 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * @param requestContext current request context
      * @param response the response to populate
      */
-    protected void populateStatusResponse(SAML1ProfileRequestContext requestContext, ResponseAbstractType response) {
+    protected void populateStatusResponse(BaseSAML1ProfileRequestContext<?,?,?> requestContext, ResponseAbstractType response) {
         response.setID(getIdGenerator().generateIdentifier());
 
-        SAMLObject samlMessage = requestContext.getSamlRequest();
+        SAMLObject samlMessage = requestContext.getInboundSAMLMessage();
         if (samlMessage != null && samlMessage instanceof RequestAbstractType) {
             response.setInResponseTo(((RequestAbstractType) samlMessage).getID());
         }
@@ -489,14 +485,14 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if attributes can not be resolved
      */
-    protected void resolveAttributes(SAML1ProfileRequestContext requestContext) throws ProfileException {
+    protected void resolveAttributes(BaseSAML1ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
         AbstractSAML1ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
         SAML1AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
 
         try {
             if (log.isDebugEnabled()) {
                 log.debug("Resolving attributes for principal " + requestContext.getPrincipalName()
-                        + " of SAML request from relying party " + requestContext.getRelyingPartyId());
+                        + " of SAML request from relying party " + requestContext.getRelyingPartyEntityId());
             }
             Map<String, BaseAttribute> principalAttributes = attributeAuthority
                     .getAttributes(buildAttributeRequestContext(requestContext));
@@ -504,10 +500,10 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
             requestContext.setPrincipalAttributes(principalAttributes);
         } catch (AttributeRequestException e) {
             log.error("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "Error resolving attributes"));
             throw new ProfileException("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
@@ -521,12 +517,12 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if there is a problem making the query
      */
-    protected AttributeStatement buildAttributeStatement(SAML1ProfileRequestContext requestContext,
+    protected AttributeStatement buildAttributeStatement(BaseSAML1ProfileRequestContext<?,?,?> requestContext,
             String subjectConfMethod) throws ProfileException {
 
         if (log.isDebugEnabled()) {
             log.debug("Creating attribute statement in response to SAML request from relying party "
-                    + requestContext.getRelyingPartyId());
+                    + requestContext.getRelyingPartyEntityId());
         }
 
         AbstractSAML1ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
@@ -534,8 +530,8 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
 
         try {
             AttributeStatement statment;
-            if (requestContext.getSamlRequest() instanceof AttributeQuery) {
-                statment = attributeAuthority.buildAttributeStatement((AttributeQuery) requestContext.getSamlRequest(),
+            if (requestContext.getInboundSAMLMessage() instanceof AttributeQuery) {
+                statment = attributeAuthority.buildAttributeStatement((AttributeQuery) requestContext.getInboundSAMLMessage(),
                         requestContext.getPrincipalAttributes().values());
             } else {
                 statment = attributeAuthority.buildAttributeStatement(null, requestContext.getPrincipalAttributes()
@@ -561,13 +557,13 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if the principal name can not be resolved
      */
-    protected void resolvePrincipal(SAML1ProfileRequestContext requestContext) throws ProfileException {
+    protected void resolvePrincipal(BaseSAML1ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
         AbstractSAML1ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
         SAML1AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
 
         if (log.isDebugEnabled()) {
             log.debug("Resolving principal name for subject of SAML request from relying party "
-                    + requestContext.getRelyingPartyId());
+                    + requestContext.getRelyingPartyEntityId());
         }
 
         try {
@@ -575,11 +571,11 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
             requestContext.setPrincipalName(principal);
         } catch (AttributeRequestException e) {
             log.error("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, StatusCode.REQUEST_DENIED,
                     "Error resolving principal"));
             throw new ProfileException("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
@@ -591,12 +587,12 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * @return created query context
      */
     protected ShibbolethSAMLAttributeRequestContext<NameIdentifier, AttributeQuery> buildAttributeRequestContext(
-            SAML1ProfileRequestContext requestContext) {
+            BaseSAML1ProfileRequestContext<?,?,?> requestContext) {
 
         ShibbolethSAMLAttributeRequestContext<NameIdentifier, AttributeQuery> queryContext;
 
-        if (requestContext.getSamlRequest() instanceof Request) {
-            Request samlRequest = (Request) requestContext.getSamlRequest();
+        if (requestContext.getInboundSAMLMessage() instanceof Request) {
+            Request samlRequest = (Request) requestContext.getInboundSAMLMessage();
             queryContext = new ShibbolethSAMLAttributeRequestContext<NameIdentifier, AttributeQuery>(
                     getMetadataProvider(), requestContext.getRelyingPartyConfiguration(), samlRequest
                             .getAttributeQuery());
@@ -605,7 +601,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
                     getMetadataProvider(), requestContext.getRelyingPartyConfiguration(), null);
         }
 
-        queryContext.setAttributeRequester(requestContext.getAssertingPartyId());
+        queryContext.setAttributeRequester(requestContext.getAssertingPartyEntityId());
         queryContext.setPrincipalName(requestContext.getPrincipalName());
         queryContext.setProfileConfiguration(requestContext.getProfileConfiguration());
         queryContext.setRequest(requestContext.getProfileRequest());
@@ -614,7 +610,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
         if (userSession != null) {
             queryContext.setUserSession(userSession);
             ServiceInformation serviceInfo = userSession.getServicesInformation().get(
-                    requestContext.getRelyingPartyId());
+                    requestContext.getRelyingPartyEntityId());
             if (serviceInfo != null) {
                 String principalAuthenticationMethod = serviceInfo.getAuthenticationMethod().getAuthenticationMethod();
 
@@ -636,10 +632,10 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * @throws ProfileException thrown if the metadata can not be located for the relying party or, if signing is
      *             required, if a signing credential is not configured
      */
-    protected void signAssertion(SAML1ProfileRequestContext requestContext, Assertion assertion)
+    protected void signAssertion(BaseSAML1ProfileRequestContext<?,?,?> requestContext, Assertion assertion)
             throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Determining if SAML assertion to relying party " + requestContext.getRelyingPartyId()
+            log.debug("Determining if SAML assertion to relying party " + requestContext.getRelyingPartyEntityId()
                     + " should be signed");
         }
 
@@ -653,7 +649,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
             if (ssoDescriptor.getWantAssertionsSigned() != null) {
                 signAssertion = ssoDescriptor.getWantAssertionsSigned().booleanValue();
                 if (log.isDebugEnabled()) {
-                    log.debug("Entity metadata for relying party " + requestContext.getRelyingPartyId()
+                    log.debug("Entity metadata for relying party " + requestContext.getRelyingPartyEntityId()
                             + " indicates to sign assertions: " + signAssertion);
                 }
             }
@@ -670,7 +666,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
 
         if (log.isDebugEnabled()) {
             log.debug("Determining signing credntial for assertion to relying party "
-                    + requestContext.getRelyingPartyId());
+                    + requestContext.getRelyingPartyEntityId());
         }
         Credential signatureCredential = profileConfig.getSigningCredential();
         if (signatureCredential == null) {
@@ -684,7 +680,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
         }
 
         if (log.isDebugEnabled()) {
-            log.debug("Signing assertion to relying party " + requestContext.getRelyingPartyId());
+            log.debug("Signing assertion to relying party " + requestContext.getRelyingPartyEntityId());
         }
         SAMLObjectContentReference contentRef = new SAMLObjectContentReference(assertion);
         Signature signature = signatureBuilder.buildObject(Signature.DEFAULT_ELEMENT_NAME);
@@ -699,147 +695,20 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @param context current request context
      */
-    protected void writeAuditLogEntry(SAML1ProfileRequestContext context) {
+    protected void writeAuditLogEntry(BaseSAML1ProfileRequestContext<?,?,?> context) {
         AuditLogEntry auditLogEntry = new AuditLogEntry();
         auditLogEntry.setMessageProfile(getProfileId());
         auditLogEntry.setPrincipalAuthenticationMethod(context.getPrincipalAuthenticationMethod());
         auditLogEntry.setPrincipalName(context.getPrincipalName());
-        auditLogEntry.setAssertingPartyId(context.getAssertingPartyId());
-        auditLogEntry.setRelyingPartyId(context.getRelyingPartyId());
+        auditLogEntry.setAssertingPartyId(context.getAssertingPartyEntityId());
+        auditLogEntry.setRelyingPartyId(context.getRelyingPartyEntityId());
         auditLogEntry.setRequestBinding(context.getMessageDecoder());
         auditLogEntry.setRequestId(null);
         auditLogEntry.setResponseBinding(context.getMessageEncoder());
-        auditLogEntry.setResponseId(context.getSamlResponse().getID());
-        if (context.getPrincipalAttributes() != null) {
-            auditLogEntry.getReleasedAttributes().addAll(context.getPrincipalAttributes().keySet());
+        auditLogEntry.setResponseId(context.getOutboundSAMLMessageId());
+        if (context.getReleasedPrincipalAttributeIds() != null) {
+            auditLogEntry.getReleasedAttributes().addAll(context.getReleasedPrincipalAttributeIds());
         }
         getAduitLog().log(Level.CRITICAL, auditLogEntry);
     }
-
-    /**
-     * Contextual object used to accumlate information as profile requests are being processed.
-     * 
-     * @param <RequestType> type of SAML 1 request
-     * @param <ResponseType> type of SAML 1 response
-     * @param <ProfileConfigurationType> configuration type for this profile
-     */
-    protected class SAML1ProfileRequestContext<RequestType extends RequestAbstractType, ResponseType extends ResponseAbstractType, ProfileConfigurationType extends AbstractSAML1ProfileConfiguration>
-            extends SAMLProfileRequestContext {
-
-        /** SAML request message. */
-        private RequestType samlRequest;
-
-        /** SAML response message. */
-        private ResponseType samlResponse;
-
-        /** Request profile configuration. */
-        private ProfileConfigurationType profileConfiguration;
-
-        /** The NameIdentifier of the subject of this request. */
-        private NameIdentifier subjectNameIdentifier;
-
-        /** The request failure status. */
-        private Status failureStatus;
-
-        /**
-         * Constructor.
-         * 
-         * @param request current profile request
-         * @param response current profile response
-         */
-        public SAML1ProfileRequestContext(ProfileRequest<ServletRequest> request,
-                ProfileResponse<ServletResponse> response) {
-            super(request, response);
-        }
-
-        /**
-         * Gets the NameIdentifier of the subject of this request.
-         * 
-         * @return NameIdentifier of the subject of this request
-         */
-        public NameIdentifier getSubjectNameID() {
-            return subjectNameIdentifier;
-        }
-
-        /**
-         * Sets the NameIdentifier of the subject of this request.
-         * 
-         * @param id NameIdentifier of the subject of this request
-         */
-        public void setSubjectNameID(NameIdentifier id) {
-            subjectNameIdentifier = id;
-        }
-
-        /**
-         * Gets the profile configuration for this request.
-         * 
-         * @return profile configuration for this request
-         */
-        public ProfileConfigurationType getProfileConfiguration() {
-            return profileConfiguration;
-        }
-
-        /**
-         * Sets the profile configuration for this request.
-         * 
-         * @param configuration profile configuration for this request
-         */
-        public void setProfileConfiguration(ProfileConfigurationType configuration) {
-            profileConfiguration = configuration;
-        }
-
-        /**
-         * Gets the SAML request message.
-         * 
-         * @return SAML request message
-         */
-        public RequestType getSamlRequest() {
-            return samlRequest;
-        }
-
-        /**
-         * Sets the SAML request message.
-         * 
-         * @param request SAML request message
-         */
-        public void setSamlRequest(RequestType request) {
-            samlRequest = request;
-        }
-
-        /**
-         * Gets the SAML response message.
-         * 
-         * @return SAML response message
-         */
-        public ResponseType getSamlResponse() {
-            return samlResponse;
-        }
-
-        /**
-         * Sets the SAML response message.
-         * 
-         * @param response SAML response message
-         */
-        public void setSamlResponse(ResponseType response) {
-            samlResponse = response;
-        }
-
-        /**
-         * Gets the status reflecting a request failure.
-         * 
-         * @return status reflecting a request failure
-         */
-        public Status getFailureStatus() {
-            return failureStatus;
-        }
-
-        /**
-         * Sets the status reflecting a request failure.
-         * 
-         * @param status status reflecting a request failure
-         */
-        public void setFailureStatus(Status status) {
-            failureStatus = status;
-        }
-    }
 }
\ No newline at end of file
index 907e72e..40b431e 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.profile.saml1;
 
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
 
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 
 /**
  * SAML 1 Artifact Query profile handler.
@@ -35,9 +33,8 @@ public class ArtifactQuery extends AbstractSAML1ProfileHandler {
     }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
-            throws ProfileException {
+    public void processRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport) throws ProfileException {
         // TODO Auto-generated method stub
-
+        
     }
 }
\ No newline at end of file
index 36c5ec4..f6df2b6 100644 (file)
@@ -18,29 +18,24 @@ package edu.internet2.middleware.shibboleth.idp.profile.saml1;
 
 import java.util.ArrayList;
 
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
 import org.apache.log4j.Logger;
-import org.opensaml.common.binding.BindingException;
-import org.opensaml.common.binding.decoding.MessageDecoder;
-import org.opensaml.common.binding.encoding.MessageEncoder;
-import org.opensaml.common.binding.security.SAMLSecurityPolicy;
-import org.opensaml.saml1.binding.decoding.HTTPSOAP11Decoder;
-import org.opensaml.saml1.binding.encoding.HTTPSOAP11Encoder;
+import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml1.core.AttributeQuery;
 import org.opensaml.saml1.core.Request;
 import org.opensaml.saml1.core.Response;
 import org.opensaml.saml1.core.Statement;
 import org.opensaml.saml1.core.StatusCode;
-import org.opensaml.saml2.metadata.RoleDescriptor;
+import org.opensaml.saml2.metadata.AttributeAuthorityDescriptor;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.ws.message.decoder.MessageDecodingException;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
 import org.opensaml.ws.security.SecurityPolicyException;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
 
-import edu.internet2.middleware.shibboleth.common.ShibbolethConstants;
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.AttributeQueryConfiguration;
 
@@ -58,21 +53,17 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
     }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
-            throws ProfileException {
-
-        AttributeQueryContext requestContext = new AttributeQueryContext(request, response);
+    public void processRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport) throws ProfileException {
+        AttributeQueryContext requestContext = decodeRequest(inTransport, outTransport);
 
         Response samlResponse;
         try {
-            decodeRequest(requestContext);
-
             if (requestContext.getRelyingPartyConfiguration() == null) {
                 log.error("SAML 1 Attribute Query profile is not configured for relying party "
-                        + requestContext.getRelyingPartyId());
+                        + requestContext.getRelyingPartyEntityId());
                 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, StatusCode.REQUEST_DENIED,
                         "SAML 1 Attribute Query profile is not configured for relying party "
-                                + requestContext.getRelyingPartyId()));
+                                + requestContext.getRelyingPartyEntityId()));
                 samlResponse = buildErrorResponse(requestContext);
             }
 
@@ -87,39 +78,45 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
             samlResponse = buildErrorResponse(requestContext);
         }
 
-        requestContext.setSamlResponse(samlResponse);
+        requestContext.setOutboundSAMLMessage(samlResponse);
+        requestContext.setOutboundSAMLMessageId(samlResponse.getID());
+        requestContext.setOutboundSAMLMessageIssueInstant(samlResponse.getIssueInstant());
         encodeResponse(requestContext);
+        writeAuditLogEntry(requestContext);
     }
-
+    
     /**
-     * Decodes the message in the request and adds it to the request context.
+     * Decodes an incoming request and populates a created request context with the resultant information.
+     * 
+     * @param inTransport inbound message transport
+     * @param outTransport outbound message transport
      * 
-     * @param requestContext request context contianing the request to decode
+     * @return the created request context
      * 
      * @throws ProfileException throw if there is a problem decoding the request
      */
-    protected void decodeRequest(AttributeQueryContext requestContext) throws ProfileException {
+    protected AttributeQueryContext decodeRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport)
+            throws ProfileException {
         if (log.isDebugEnabled()) {
             log.debug("Decoding incomming request");
         }
-        MessageDecoder<ServletRequest> decoder = getMessageDecoderFactory().getMessageDecoder(
-                HTTPSOAP11Decoder.BINDING_URI);
-        if (decoder == null) {
-            throw new ProfileException("No request decoder was registered for binding type: "
-                    + HTTPSOAP11Decoder.BINDING_URI);
-        }
-        super.populateMessageDecoder(decoder);
 
-        ProfileRequest<ServletRequest> profileRequest = requestContext.getProfileRequest();
-        decoder.setRequest(profileRequest.getRawRequest());
-        requestContext.setMessageDecoder(decoder.getBindingURI());
+        MetadataProvider metadataProvider = getMetadataProvider();
+
+        AttributeQueryContext requestContext = new AttributeQueryContext();
+        requestContext.setMessageInTransport(inTransport);
+        requestContext.setInboundSAMLProtocol(SAMLConstants.SAML11P_NS);
+        requestContext.setMessageOutTransport(outTransport);
+        requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML11P_NS);
+        requestContext.setMetadataProvider(metadataProvider);
 
         try {
-            decoder.decode();
+            getMessageDecoder().decode(requestContext);
             if (log.isDebugEnabled()) {
                 log.debug("Decoded request");
             }
-        } catch (BindingException e) {
+            return requestContext;
+        } catch (MessageDecodingException e) {
             log.error("Error decoding attribute query message", e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "Error decoding message"));
             throw new ProfileException("Error decoding attribute query message");
@@ -130,91 +127,41 @@ 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 = decoder.getSecurityPolicy();
-            requestContext.setRelyingPartyId(securityPolicy.getIssuer());
-
-            Request request = (Request) decoder.getSAMLMessage();
-            requestContext.setSamlRequest(request);
-            requestContext.setAttributeQuery(request.getAttributeQuery());
-
-            populateRelyingPartyData(requestContext);
-
-            populateAssertingPartyData(requestContext);
-        }
-    }
-
-    /**
-     * Populates the relying party entity and role metadata and relying party configuration data.
-     * 
-     * @param requestContext current request context with relying party ID populated
-     * 
-     * @throws ProfileException thrown if metadata can not be located for the relying party
-     */
-    protected void populateRelyingPartyData(AttributeQueryContext requestContext) throws ProfileException {
-        try {
-            requestContext.setRelyingPartyMetadata(getMetadataProvider().getEntityDescriptor(
-                    requestContext.getRelyingPartyId()));
-
-            RoleDescriptor relyingPartyRole = requestContext.getRelyingPartyMetadata().getSPSSODescriptor(
-                    ShibbolethConstants.SAML11P_NS);
-
-            if (relyingPartyRole == null) {
-                relyingPartyRole = requestContext.getRelyingPartyMetadata().getSPSSODescriptor(
-                        ShibbolethConstants.SAML10P_NS);
-                if (relyingPartyRole == null) {
-                    throw new MetadataProviderException("Unable to locate SPSSO role descriptor for entity "
-                            + requestContext.getRelyingPartyId());
+            try {
+                Request attributeRequest = requestContext.getInboundSAMLMessage();
+                requestContext.setInboundSAMLMessageId(attributeRequest.getID());
+                requestContext.setInboundSAMLMessageIssueInstant(attributeRequest.getIssueInstant());
+
+                String relyingPartyId = requestContext.getRelyingPartyEntityId();
+                requestContext.setRelyingPartyMetadata(metadataProvider.getEntityDescriptor(relyingPartyId));
+                requestContext.setRelyingPartyRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+                requestContext.setRelyingPartyRoleMetadata(requestContext.getRelyingPartyMetadata().getSPSSODescriptor(
+                        SAMLConstants.SAML10P_NS));
+                RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
+                requestContext.setRelyingPartyConfiguration(rpConfig);
+
+                String assertingPartyId = requestContext.getRelyingPartyConfiguration().getProviderId();
+                requestContext.setAssertingPartyEntityId(assertingPartyId);
+                requestContext.setAssertingPartyMetadata(metadataProvider.getEntityDescriptor(assertingPartyId));
+                requestContext.setAssertingPartyRole(AttributeAuthorityDescriptor.DEFAULT_ELEMENT_NAME);
+                requestContext.setAssertingPartyRoleMetadata(requestContext.getAssertingPartyMetadata()
+                        .getAttributeAuthorityDescriptor(SAMLConstants.SAML10P_NS));
+
+                AttributeQueryConfiguration profileConfig = (AttributeQueryConfiguration) rpConfig
+                        .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID);
+                requestContext.setProfileConfiguration(profileConfig);
+                if (profileConfig.getSigningCredential() != null) {
+                    requestContext.setOutboundSAMLMessageSigningCredential(profileConfig.getSigningCredential());
+                } else if (rpConfig.getDefaultSigningCredential() != null) {
+                    requestContext.setOutboundSAMLMessageSigningCredential(rpConfig.getDefaultSigningCredential());
                 }
-            }
-            requestContext.setRelyingPartyRoleMetadata(relyingPartyRole);
 
-            RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(requestContext.getRelyingPartyId());
-            requestContext.setRelyingPartyConfiguration(rpConfig);
-
-            requestContext.setProfileConfiguration((AttributeQueryConfiguration) rpConfig
-                    .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID));
-
-        } catch (MetadataProviderException e) {
-            log.error("Unable to locate metadata for relying party " + requestContext.getRelyingPartyId());
-            requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null,
-                    "Unable to locate metadata for relying party " + requestContext.getRelyingPartyId()));
-            throw new ProfileException("Unable to locate metadata for relying party "
-                    + requestContext.getRelyingPartyId());
-        }
-    }
-
-    /**
-     * Populates the asserting party entity and role metadata.
-     * 
-     * @param requestContext current request context with relying party configuration populated
-     * 
-     * @throws ProfileException thrown if metadata can not be located for the asserting party
-     */
-    protected void populateAssertingPartyData(AttributeQueryContext requestContext) throws ProfileException {
-        String assertingPartyId = requestContext.getRelyingPartyConfiguration().getProviderId();
-
-        try {
-            requestContext.setAssertingPartyId(assertingPartyId);
-
-            requestContext.setAssertingPartyMetadata(getMetadataProvider().getEntityDescriptor(assertingPartyId));
-
-            RoleDescriptor assertingPartyRole = requestContext.getAssertingPartyMetadata()
-                    .getAttributeAuthorityDescriptor(ShibbolethConstants.SAML11P_NS);
-
-            if (assertingPartyRole == null) {
-                assertingPartyRole = requestContext.getAssertingPartyMetadata().getAttributeAuthorityDescriptor(
-                        ShibbolethConstants.SAML10P_NS);
-                if (assertingPartyRole == null) {
-                    throw new MetadataProviderException("Unable to locate IDPSSO role descriptor for entity "
-                            + assertingPartyId);
-                }
+            } catch (MetadataProviderException e) {
+                log.error("Unable to locate metadata for asserting or relying party");
+                requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null,
+                        "Error locating party metadata"));
+                throw new ProfileException("Error locating party metadata");
             }
-            requestContext.setAssertingPartyRoleMetadata(assertingPartyRole);
-        } catch (MetadataProviderException e) {
-            log.error("Unable to locate metadata for asserting party " + assertingPartyId);
-            requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null,
-                    "Unable to locate metadata for relying party " + assertingPartyId));
-            throw new ProfileException("Unable to locate metadata for relying party " + assertingPartyId);
         }
     }
 
@@ -227,49 +174,26 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
      */
     protected void encodeResponse(AttributeQueryContext requestContext) throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request from relying party " + requestContext.getRelyingPartyId());
-        }
-        MessageEncoder<ServletResponse> encoder = getMessageEncoderFactory().getMessageEncoder(
-                HTTPSOAP11Encoder.BINDING_URI);
-        if (encoder == null) {
-            throw new ProfileException("No response encoder was registered for binding type: "
-                    + HTTPSOAP11Encoder.BINDING_URI);
+            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getRelyingPartyEntityId());
         }
 
-        super.populateMessageEncoder(encoder);
-        encoder.setRelayState(requestContext.getRelayState());
-        ProfileResponse<ServletResponse> profileResponse = requestContext.getProfileResponse();
-        encoder.setResponse(profileResponse.getRawResponse());
-        encoder.setSamlMessage(requestContext.getSamlResponse());
-        requestContext.setMessageEncoder(encoder.getBindingURI());
-
         try {
-            encoder.encode();
-        } catch (BindingException e) {
+            getMessageEncoder().encode(requestContext);
+        } catch (MessageEncodingException e) {
             throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
     /** Basic data structure used to accumulate information as a request is being processed. */
     protected class AttributeQueryContext extends
-            SAML1ProfileRequestContext<Request, Response, AttributeQueryConfiguration> {
+            BaseSAML1ProfileRequestContext<Request, Response, AttributeQueryConfiguration> {
 
         /** Current attribute query. */
         private AttributeQuery attributeQuery;
 
         /**
-         * Constructor.
-         * 
-         * @param request current profile request
-         * @param response current profile response
-         */
-        public AttributeQueryContext(ProfileRequest<ServletRequest> request, 
-                ProfileResponse<ServletResponse> response) {
-            super(request, response);
-        }
-
-        /**
          * Gets the attribute query of the request.
          * 
          * @return attribute query of the request
diff --git a/src/edu/internet2/middleware/shibboleth/idp/profile/saml1/BaseSAML1ProfileRequestContext.java b/src/edu/internet2/middleware/shibboleth/idp/profile/saml1/BaseSAML1ProfileRequestContext.java
new file mode 100644 (file)
index 0000000..1cb527a
--- /dev/null
@@ -0,0 +1,44 @@
+
+package edu.internet2.middleware.shibboleth.idp.profile.saml1;
+
+import org.opensaml.saml1.core.NameIdentifier;
+import org.opensaml.saml1.core.RequestAbstractType;
+import org.opensaml.saml1.core.ResponseAbstractType;
+import org.opensaml.saml1.core.Status;
+
+import edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAMLAttributeRequestContext;
+import edu.internet2.middleware.shibboleth.common.profile.provider.BaseShibbolethProfileRequestContext;
+import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.AbstractSAML1ProfileConfiguration;
+
+/**
+ * Contextual object used to accumlate information as profile requests are being processed.
+ * 
+ * @param <RequestType> type of SAML 1 request
+ * @param <ResponseType> type of SAML 1 response
+ * @param <ProfileConfigurationType> configuration type for this profile
+ */
+public abstract class BaseSAML1ProfileRequestContext<RequestType extends RequestAbstractType, ResponseType extends ResponseAbstractType, ProfileConfigurationType extends AbstractSAML1ProfileConfiguration>
+        extends BaseShibbolethProfileRequestContext<RequestType, ResponseType, ProfileConfigurationType>
+        implements ShibbolethSAMLAttributeRequestContext<NameIdentifier, RequestType, ResponseType, ProfileConfigurationType> {
+
+    /** The request failure status. */
+    private Status failureStatus;
+
+    /**
+     * Gets the status reflecting a request failure.
+     * 
+     * @return status reflecting a request failure
+     */
+    public Status getFailureStatus() {
+        return failureStatus;
+    }
+
+    /**
+     * Sets the status reflecting a request failure.
+     * 
+     * @param status status reflecting a request failure
+     */
+    public void setFailureStatus(Status status) {
+        failureStatus = status;
+    }
+}
\ No newline at end of file
index c2758e5..a07780f 100644 (file)
@@ -24,8 +24,6 @@ import java.util.List;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
@@ -33,8 +31,7 @@ import javax.servlet.http.HttpSession;
 import org.apache.log4j.Logger;
 import org.opensaml.common.SAMLObjectBuilder;
 import org.opensaml.common.binding.BasicEndpointSelector;
-import org.opensaml.common.binding.BindingException;
-import org.opensaml.common.binding.encoding.MessageEncoder;
+import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml1.core.AuthenticationStatement;
 import org.opensaml.saml1.core.Request;
 import org.opensaml.saml1.core.Response;
@@ -44,16 +41,23 @@ import org.opensaml.saml1.core.Subject;
 import org.opensaml.saml1.core.SubjectLocality;
 import org.opensaml.saml2.metadata.AssertionConsumerService;
 import org.opensaml.saml2.metadata.Endpoint;
-import org.opensaml.saml2.metadata.RoleDescriptor;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.IDPSSODescriptor;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+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.util.DatatypeHelper;
 
 import edu.internet2.middleware.shibboleth.common.ShibbolethConstants;
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.ShibbolethSSOConfiguration;
+import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml2.SSOConfiguration;
 import edu.internet2.middleware.shibboleth.common.util.HttpHelper;
 import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
 import edu.internet2.middleware.shibboleth.idp.authn.ShibbolethSSOLoginContext;
@@ -72,7 +76,7 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
 
     /** URL of the authentication manager servlet. */
     private String authenticationManagerPath;
-    
+
     /** URI of SAML 1 bindings supported for outgoing message encoding. */
     private ArrayList<String> supportedOutgoingBindings;
 
@@ -90,8 +94,8 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
             throw new IllegalArgumentException("Authentication manager path may not be null");
         }
         authenticationManagerPath = authnManagerPath;
-        
-        if(outgoingBindings == null || outgoingBindings.isEmpty()){
+
+        if (outgoingBindings == null || outgoingBindings.isEmpty()) {
             throw new IllegalArgumentException("List of supported outgoing bindings may not be empty");
         }
         supportedOutgoingBindings = new ArrayList<String>(outgoingBindings);
@@ -109,27 +113,24 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
     }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
-            throws ProfileException {
-
-        if (response.getRawResponse().isCommitted()) {
-            log.error("HTTP Response already committed");
-        }
-
+    public void processRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport) throws ProfileException {
         if (log.isDebugEnabled()) {
             log.debug("Processing incomming request");
         }
-        HttpSession httpSession = ((HttpServletRequest) request.getRawRequest()).getSession(true);
+
+        HttpServletRequest httpRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
+        HttpSession httpSession = httpRequest.getSession();
+
         if (httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY) == null) {
             if (log.isDebugEnabled()) {
                 log.debug("User session does not contain a login context, processing as first leg of request");
             }
-            performAuthentication(request, response);
+            performAuthentication(inTransport, outTransport);
         } else {
             if (log.isDebugEnabled()) {
                 log.debug("User session contains a login context, processing as second leg of request");
             }
-            completeAuthenticationRequest(request, response);
+            completeAuthenticationRequest(inTransport, outTransport);
         }
     }
 
@@ -137,17 +138,17 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
      * Creates a {@link LoginContext} an sends the request off to the AuthenticationManager to begin the process of
      * authenticating the user.
      * 
-     * @param request current request
-     * @param response current response
+     * @param inTransport inbound message transport
+     * @param outTransport outbound message transport
      * 
      * @throws ProfileException thrown if there is a problem creating the login context and transferring control to the
      *             authentication manager
      */
-    protected void performAuthentication(ProfileRequest<ServletRequest> request,
-            ProfileResponse<ServletResponse> response) throws ProfileException {
+    protected void performAuthentication(HTTPInTransport inTransport, HTTPOutTransport outTransport)
+            throws ProfileException {
 
-        HttpServletRequest httpRequest = (HttpServletRequest) request.getRawRequest();
-        HttpServletResponse httpResponse = (HttpServletResponse) response.getRawResponse();
+        HttpServletRequest httpRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
+        HttpServletResponse httpResponse = ((HttpServletResponseAdapter) outTransport).getWrappedResponse();
         HttpSession httpSession = httpRequest.getSession(true);
 
         LoginContext loginContext = buildLoginContext(httpRequest);
@@ -176,20 +177,21 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
      * Creates a response to the Shibboleth SSO and sends the user, with response in tow, back to the relying party
      * after they've been authenticated.
      * 
-     * @param request current request
-     * @param response current response
+     * @param inTransport inbound message transport
+     * @param outTransport outbound message transport
      * 
      * @throws ProfileException thrown if the response can not be created and sent back to the relying party
      */
-    protected void completeAuthenticationRequest(ProfileRequest<ServletRequest> request,
-            ProfileResponse<ServletResponse> response) throws ProfileException {
-        HttpSession httpSession = ((HttpServletRequest) request.getRawRequest()).getSession(true);
+    protected void completeAuthenticationRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport)
+            throws ProfileException {
+        HttpServletRequest httpRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
+        HttpSession httpSession = httpRequest.getSession(true);
 
         ShibbolethSSOLoginContext loginContext = (ShibbolethSSOLoginContext) httpSession
                 .getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
         httpSession.removeAttribute(LoginContext.LOGIN_CONTEXT_KEY);
 
-        ShibbolethSSORequestContext requestContext = buildRequestContext(loginContext, request, response);
+        ShibbolethSSORequestContext requestContext = buildRequestContext(loginContext, inTransport, outTransport);
 
         Response samlResponse;
         try {
@@ -197,9 +199,9 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
                 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "User failed authentication"));
                 throw new ProfileException("User failed authentication");
             }
-            
+
             resolveAttributes(requestContext);
-            
+
             ArrayList<Statement> statements = new ArrayList<Statement>();
             statements.add(buildAuthenticationStatement(requestContext));
             if (requestContext.getProfileConfiguration().includeAttributeStatement()) {
@@ -211,7 +213,9 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
             samlResponse = buildErrorResponse(requestContext);
         }
 
-        requestContext.setSamlResponse(samlResponse);
+        requestContext.setOutboundSAMLMessage(samlResponse);
+        requestContext.setOutboundSAMLMessageId(samlResponse.getID());
+        requestContext.setOutboundSAMLMessageIssueInstant(samlResponse.getIssueInstant());
         encodeResponse(requestContext);
         writeAuditLogEntry(requestContext);
     }
@@ -270,104 +274,95 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
      * Creates an authentication request context from the current environmental information.
      * 
      * @param loginContext current login context
-     * @param request current request
-     * @param response current response
+     * @param in inbound transport
+     * @param out outbount transport
      * 
      * @return created authentication request context
      * 
-     * @throws ProfileException thrown if asserting and relying party metadata can not be located
+     * @throws ProfileException thrown if there is a problem creating the context
      */
     protected ShibbolethSSORequestContext buildRequestContext(ShibbolethSSOLoginContext loginContext,
-            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());
+            HTTPInTransport in, HTTPOutTransport out) throws ProfileException {
+        ShibbolethSSORequestContext requestContext = new ShibbolethSSORequestContext();
 
-        requestContext.setPrincipalAuthenticationMethod(loginContext.getAuthenticationMethod());
-
-        String relyingPartyId = loginContext.getRelyingPartyId();
-
-        requestContext.setRelyingPartyId(relyingPartyId);
-
-        populateRelyingPartyData(requestContext);
-
-        populateAssertingPartyData(requestContext);
-
-        return requestContext;
-    }
-
-    /**
-     * Populates the relying party entity and role metadata and relying party configuration data.
-     * 
-     * @param requestContext current request context with relying party ID populated
-     * 
-     * @throws ProfileException thrown if metadata can not be located for the relying party
-     */
-    protected void populateRelyingPartyData(ShibbolethSSORequestContext requestContext) throws ProfileException {
         try {
-            requestContext.setRelyingPartyMetadata(getMetadataProvider().getEntityDescriptor(
-                    requestContext.getRelyingPartyId()));
-
-            RoleDescriptor relyingPartyRole = requestContext.getRelyingPartyMetadata().getSPSSODescriptor(
-                    ShibbolethConstants.SAML11P_NS);
-
-            if (relyingPartyRole == null) {
-                relyingPartyRole = requestContext.getRelyingPartyMetadata().getSPSSODescriptor(
-                        ShibbolethConstants.SAML10P_NS);
-                if (relyingPartyRole == null) {
-                    throw new MetadataProviderException("Unable to locate SPSSO role descriptor for entity "
-                            + requestContext.getRelyingPartyId());
-                }
-            }
-            requestContext.setRelyingPartyRoleMetadata(relyingPartyRole);
-
-            RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(requestContext.getRelyingPartyId());
+            requestContext.setLoginContext(loginContext);
+            requestContext.setPrincipalName(loginContext.getPrincipalName());
+            requestContext.setPrincipalAuthenticationMethod(loginContext.getAuthenticationMethod());
+            requestContext.setUserSession(getUserSession(in));
+            requestContext.setRelayState(loginContext.getSpTarget());
+
+            requestContext.setMessageInTransport(in);
+            requestContext.setInboundSAMLProtocol(ShibbolethConstants.SHIB_SSO_PROFILE_URI);
+
+            MetadataProvider metadataProvider = getMetadataProvider();
+            requestContext.setMetadataProvider(metadataProvider);
+
+            String relyingPartyId = loginContext.getRelyingPartyId();
+            requestContext.setRelyingPartyEntityId(relyingPartyId);
+            EntityDescriptor relyingPartyMetadata = metadataProvider.getEntityDescriptor(relyingPartyId);
+            requestContext.setRelyingPartyMetadata(relyingPartyMetadata);
+            requestContext.setRelyingPartyRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+            requestContext.setRelyingPartyRoleMetadata(relyingPartyMetadata
+                    .getSPSSODescriptor(SAMLConstants.SAML11P_NS));
+            RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
             requestContext.setRelyingPartyConfiguration(rpConfig);
+            requestContext.setRelyingPartyEndpoint(selectEndpoint(requestContext));
+
+            String assertingPartyId = rpConfig.getProviderId();
+            requestContext.setAssertingPartyEntityId(assertingPartyId);
+            EntityDescriptor assertingPartyMetadata = metadataProvider.getEntityDescriptor(assertingPartyId);
+            requestContext.setAssertingPartyMetadata(assertingPartyMetadata);
+            requestContext.setAssertingPartyRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
+            requestContext.setAssertingPartyRoleMetadata(assertingPartyMetadata
+                    .getIDPSSODescriptor(SAMLConstants.SAML20P_NS));
+
+            requestContext.setMessageOutTransport(out);
+            requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML20P_NS);
+            ShibbolethSSOConfiguration profileConfig = (ShibbolethSSOConfiguration) rpConfig
+                    .getProfileConfiguration(SSOConfiguration.PROFILE_ID);
+            requestContext.setProfileConfiguration(profileConfig);
+            if (profileConfig.getSigningCredential() != null) {
+                requestContext.setOutboundSAMLMessageSigningCredential(profileConfig.getSigningCredential());
+            } else if (rpConfig.getDefaultSigningCredential() != null) {
+                requestContext.setOutboundSAMLMessageSigningCredential(rpConfig.getDefaultSigningCredential());
+            }
 
-            requestContext.setProfileConfiguration((ShibbolethSSOConfiguration) rpConfig
-                    .getProfileConfiguration(ShibbolethSSOConfiguration.PROFILE_ID));
-
+            return requestContext;
         } catch (MetadataProviderException e) {
-            log.error("Unable to locate metadata for relying party " + requestContext.getRelyingPartyId());
-            requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null,
-                    "Unable to locate metadata for relying party " + requestContext.getRelyingPartyId()));
-            throw new ProfileException("Unable to locate metadata for relying party "
-                    + requestContext.getRelyingPartyId());
+            log.error("Unable to locate metadata for asserting or relying party");
+            requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "Error locating party metadata"));
+            throw new ProfileException("Error locating party metadata");
         }
     }
 
     /**
-     * Populates the asserting party entity and role metadata.
+     * Selects the appropriate endpoint for the relying party and stores it in the request context.
      * 
-     * @param requestContext current request context with relying party configuration populated
+     * @param requestContext current request context
      * 
-     * @throws ProfileException thrown if metadata can not be located for the asserting party
+     * @return Endpoint selected from the information provided in the request context
      */
-    protected void populateAssertingPartyData(ShibbolethSSORequestContext requestContext) throws ProfileException {
-        String assertingPartyId = requestContext.getRelyingPartyConfiguration().getProviderId();
-
-        try {
-            requestContext.setAssertingPartyId(assertingPartyId);
-
-            requestContext.setAssertingPartyMetadata(getMetadataProvider().getEntityDescriptor(assertingPartyId));
+    protected Endpoint selectEndpoint(ShibbolethSSORequestContext requestContext) {
+        ShibbolethSSOLoginContext loginContext = requestContext.getLoginContext();
 
-            RoleDescriptor assertingPartyRole = requestContext.getAssertingPartyMetadata().getIDPSSODescriptor(
-                    ShibbolethConstants.SHIB_SSO_PROFILE_URI);
-            if (assertingPartyRole == null) {
-                throw new MetadataProviderException("Unable to locate IDPSSO role descriptor for entity "
-                        + assertingPartyId);
-            }
-            requestContext.setAssertingPartyRoleMetadata(assertingPartyRole);
-        } catch (MetadataProviderException e) {
-            log.error("Unable to locate metadata for asserting party " + assertingPartyId);
-            requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null,
-                    "Unable to locate metadata for relying party " + assertingPartyId));
-            throw new ProfileException("Unable to locate metadata for relying party " + assertingPartyId);
+        if (loginContext.getSpAssertionConsumerService() != null) {
+            SAMLObjectBuilder<AssertionConsumerService> acsBuilder = (SAMLObjectBuilder<AssertionConsumerService>) getBuilderFactory()
+                    .getBuilder(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
+            AssertionConsumerService acsEndpoint = acsBuilder.buildObject();
+            acsEndpoint.setBinding(getMessageEncoder().getBindingURI());
+            acsEndpoint.setLocation(loginContext.getSpAssertionConsumerService());
+            return acsEndpoint;
         }
+
+        BasicEndpointSelector endpointSelector = new BasicEndpointSelector();
+        endpointSelector.setEndpointType(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
+        endpointSelector.setMetadataProvider(getMetadataProvider());
+        endpointSelector.setRelyingParty(requestContext.getRelyingPartyMetadata());
+        endpointSelector.setRelyingPartyRole(requestContext.getRelyingPartyRoleMetadata());
+        endpointSelector.setSamlRequest(requestContext.getInboundSAMLMessage());
+        endpointSelector.getSupportedIssuerBindings().addAll(supportedOutgoingBindings);
+        return endpointSelector.selectEndpoint();
     }
 
     /**
@@ -405,9 +400,9 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
     protected SubjectLocality buildSubjectLocality(ShibbolethSSORequestContext requestContext) {
         SubjectLocality subjectLocality = subjectLocalityBuilder.buildObject();
 
-        HttpServletRequest httpRequest = (HttpServletRequest) requestContext.getProfileRequest().getRawRequest();
-        subjectLocality.setIPAddress(httpRequest.getRemoteAddr());
-        subjectLocality.setDNSAddress(httpRequest.getRemoteHost());
+        HTTPInTransport inTransport = (HTTPInTransport) requestContext.getMessageInTransport();
+        subjectLocality.setIPAddress(inTransport.getPeerAddress());
+        subjectLocality.setDNSAddress(inTransport.getPeerDomainName());
 
         return subjectLocality;
     }
@@ -421,64 +416,26 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
      */
     protected void encodeResponse(ShibbolethSSORequestContext requestContext) throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request from relying party " + requestContext.getRelyingPartyId());
-        }
-
-        Endpoint relyingPartyEndpoint;
-
-        BasicEndpointSelector endpointSelector = new BasicEndpointSelector();
-        endpointSelector.setEndpointType(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
-        endpointSelector.setMetadataProvider(getMetadataProvider());
-        endpointSelector.setRelyingParty(requestContext.getRelyingPartyMetadata());
-        endpointSelector.setRelyingPartyRole(requestContext.getRelyingPartyRoleMetadata());
-        endpointSelector.setSamlRequest(requestContext.getSamlRequest());
-        endpointSelector.getSupportedIssuerBindings().addAll(supportedOutgoingBindings);
-        relyingPartyEndpoint = endpointSelector.selectEndpoint();
-
-        if (relyingPartyEndpoint == null) {
-            log.error("Unable to determine endpoint, from metadata, for relying party "
-                    + requestContext.getRelyingPartyId() + " acting in SPSSO role");
-            throw new ProfileException("Unable to determine endpoint, from metadata, for relying party "
-                    + requestContext.getRelyingPartyId() + " acting in SPSSO role");
+            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getRelyingPartyEntityId());
         }
 
-        MessageEncoder<ServletResponse> encoder = getMessageEncoderFactory().getMessageEncoder(
-                relyingPartyEndpoint.getBinding());
-        encoder.setRelyingPartyEndpoint(relyingPartyEndpoint);
-        super.populateMessageEncoder(encoder);
-        encoder.setRelayState(requestContext.getRelayState());
-        ProfileResponse<ServletResponse> profileResponse = requestContext.getProfileResponse();
-        encoder.setResponse(profileResponse.getRawResponse());
-        encoder.setSamlMessage(requestContext.getSamlResponse());
-        requestContext.setMessageEncoder(encoder.getBindingURI());
-
         try {
-            encoder.encode();
-        } catch (BindingException e) {
+            getMessageEncoder().encode(requestContext);
+        } catch (MessageEncodingException e) {
             throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
     /** Represents the internal state of a Shibboleth SSO Request while it's being processed by the IdP. */
     protected class ShibbolethSSORequestContext extends
-            SAML1ProfileRequestContext<Request, Response, ShibbolethSSOConfiguration> {
+            BaseSAML1ProfileRequestContext<Request, Response, ShibbolethSSOConfiguration> {
 
         /** Current login context. */
         private ShibbolethSSOLoginContext loginContext;
 
         /**
-         * Constructor.
-         * 
-         * @param request current profile request
-         * @param response current profile response
-         */
-        public ShibbolethSSORequestContext(ProfileRequest<ServletRequest> request,
-                ProfileResponse<ServletResponse> response) {
-            super(request, response);
-        }
-
-        /**
          * Gets the current login context.
          * 
          * @return current login context
index 7eceb9d..16ba5a1 100644 (file)
@@ -22,10 +22,10 @@ import java.util.List;
 import java.util.Map;
 
 import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 
 import org.apache.log4j.Logger;
 import org.joda.time.DateTime;
+import org.opensaml.common.SAMLObject;
 import org.opensaml.common.SAMLObjectBuilder;
 import org.opensaml.common.SAMLVersion;
 import org.opensaml.common.impl.SAMLObjectContentReference;
@@ -58,6 +58,7 @@ import org.opensaml.saml2.metadata.PDPDescriptor;
 import org.opensaml.saml2.metadata.RoleDescriptor;
 import org.opensaml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.saml2.metadata.SSODescriptor;
+import org.opensaml.ws.transport.http.HTTPInTransport;
 import org.opensaml.xml.XMLObjectBuilder;
 import org.opensaml.xml.security.credential.Credential;
 import org.opensaml.xml.signature.Signature;
@@ -73,8 +74,7 @@ import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML2Attrib
 import edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAMLAttributeRequestContext;
 import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
+import edu.internet2.middleware.shibboleth.common.relyingparty.ProfileConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml2.AbstractSAML2ProfileConfiguration;
 import edu.internet2.middleware.shibboleth.idp.profile.AbstractSAMLProfileHandler;
 import edu.internet2.middleware.shibboleth.idp.session.ServiceInformation;
@@ -167,8 +167,8 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if the major version of the SAML request is not 2
      */
-    protected void checkSamlVersion(SAML2ProfileRequestContext requestContext) throws ProfileException {
-        SAMLVersion version = requestContext.getSamlRequest().getVersion();
+    protected void checkSamlVersion(BaseSAML2ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
+        SAMLVersion version = requestContext.getInboundSAMLMessage().getVersion();
         if (version.getMajorVersion() < 2) {
             requestContext.setFailureStatus(buildStatus(StatusCode.VERSION_MISMATCH_URI,
                     StatusCode.REQUEST_VERSION_TOO_LOW_URI, null));
@@ -191,7 +191,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if there is a problem creating the SAML response
      */
-    protected Response buildResponse(SAML2ProfileRequestContext requestContext, String subjectConfirmationMethod,
+    protected Response buildResponse(BaseSAML2ProfileRequestContext<?,?,?> requestContext, String subjectConfirmationMethod,
             List<Statement> statements) throws ProfileException {
 
         DateTime issueInstant = new DateTime();
@@ -229,7 +229,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @return the built assertion
      */
-    protected Assertion buildAssertion(SAML2ProfileRequestContext requestContext, DateTime issueInstant) {
+    protected Assertion buildAssertion(BaseSAML2ProfileRequestContext<?,?,?> requestContext, DateTime issueInstant) {
         Assertion assertion = assertionBuilder.buildObject();
         assertion.setID(getIdGenerator().generateIdentifier());
         assertion.setIssueInstant(issueInstant);
@@ -249,10 +249,10 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @return the built issuer
      */
-    protected Issuer buildEntityIssuer(SAML2ProfileRequestContext requestContext) {
+    protected Issuer buildEntityIssuer(BaseSAML2ProfileRequestContext<?,?,?> requestContext) {
         Issuer issuer = issuerBuilder.buildObject();
         issuer.setFormat(Issuer.ENTITY);
-        issuer.setValue(requestContext.getAssertingPartyId());
+        issuer.setValue(requestContext.getAssertingPartyEntityId());
 
         return issuer;
     }
@@ -266,7 +266,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @return constructed conditions
      */
-    protected Conditions buildConditions(SAML2ProfileRequestContext requestContext, DateTime issueInstant) {
+    protected Conditions buildConditions(BaseSAML2ProfileRequestContext<?,?,?> requestContext, DateTime issueInstant) {
         AbstractSAML2ProfileConfiguration profileConfig = requestContext.getProfileConfiguration();
 
         Conditions conditions = conditionsBuilder.buildObject();
@@ -311,10 +311,10 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * @param requestContext current request context
      * @param response the response to populate
      */
-    protected void populateStatusResponse(SAML2ProfileRequestContext requestContext, StatusResponseType response) {
+    protected void populateStatusResponse(BaseSAML2ProfileRequestContext<?,?,?> requestContext, StatusResponseType response) {
         response.setID(getIdGenerator().generateIdentifier());
-        if (requestContext.getSamlRequest() != null) {
-            response.setInResponseTo(requestContext.getSamlRequest().getID());
+        if (requestContext.getInboundSAMLMessage() != null) {
+            response.setInResponseTo(requestContext.getInboundSAMLMessageId());
         }
         response.setVersion(SAMLVersion.VERSION_20);
         response.setIssuer(buildEntityIssuer(requestContext));
@@ -327,27 +327,27 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if there is a problem resolved attributes
      */
-    protected void resolveAttributes(SAML2ProfileRequestContext requestContext) throws ProfileException{
+    protected void resolveAttributes(BaseSAML2ProfileRequestContext<?,?,?> requestContext) throws ProfileException{
         AbstractSAML2ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
         SAML2AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
 
         try {
             if (log.isDebugEnabled()) {
                 log.debug("Resolving attributes for principal " + requestContext.getPrincipalName()
-                        + " of SAML request " + requestContext.getSamlRequest().getID() + " from relying party "
-                        + requestContext.getRelyingPartyId());
+                        + " of SAML request " + requestContext.getInboundSAMLMessageId() + " from relying party "
+                        + requestContext.getRelyingPartyEntityId());
             }
             Map<String, BaseAttribute> principalAttributes = attributeAuthority
                     .getAttributes(buildAttributeRequestContext(requestContext));
 
             requestContext.setPrincipalAttributes(principalAttributes);
         } catch (AttributeRequestException e) {
-            log.error("Error resolving attributes for SAML request " + requestContext.getSamlRequest().getID()
-                    + " from relying party " + requestContext.getRelyingPartyId(), e);
+            log.error("Error resolving attributes for SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getRelyingPartyEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, null, "Error resolving attributes"));
             throw new ProfileException("Error resolving attributes for SAML request "
-                    + requestContext.getSamlRequest().getID() + " from relying party "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getInboundSAMLMessageId() + " from relying party "
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
@@ -360,18 +360,18 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if there is a problem making the query
      */
-    protected AttributeStatement buildAttributeStatement(SAML2ProfileRequestContext requestContext)
+    protected AttributeStatement buildAttributeStatement(BaseSAML2ProfileRequestContext<?,?,?> requestContext)
             throws ProfileException {
         if (log.isDebugEnabled()) {
             log.debug("Creating attribute statement in response to SAML request "
-                    + requestContext.getSamlRequest().getID() + " from relying party "
-                    + requestContext.getRelyingPartyId());
+                    + requestContext.getInboundSAMLMessageId() + " from relying party "
+                    + requestContext.getRelyingPartyEntityId());
         }
         AbstractSAML2ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
         SAML2AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
         try {
-            if (requestContext.getSamlRequest() instanceof AttributeQuery) {
-                return attributeAuthority.buildAttributeStatement((AttributeQuery) requestContext.getSamlRequest(),
+            if (requestContext.getInboundSAMLMessage() instanceof AttributeQuery) {
+                return attributeAuthority.buildAttributeStatement((AttributeQuery) requestContext.getInboundSAMLMessage(),
                         requestContext.getPrincipalAttributes().values());
             } else {
                 return attributeAuthority.buildAttributeStatement(null, requestContext.getPrincipalAttributes().values());
@@ -390,79 +390,39 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if the principal name can not be resolved
      */
-    protected void resolvePrincipal(SAML2ProfileRequestContext requestContext) throws ProfileException {
+    protected void resolvePrincipal(BaseSAML2ProfileRequestContext<RequestAbstractType, StatusResponseType, AbstractSAML2ProfileConfiguration> requestContext) throws ProfileException {
         AbstractSAML2ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
         if (profileConfiguration == null) {
             log.error("Unable to resolve principal, no SAML 2 profile configuration for relying party "
-                    + requestContext.getRelyingPartyId());
+                    + requestContext.getRelyingPartyEntityId());
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.REQUEST_DENIED_URI,
                     "Error resolving principal"));
             throw new ProfileException(
                     "Unable to resolve principal, no SAML 2 profile configuration for relying party "
-                            + requestContext.getRelyingPartyId());
+                            + requestContext.getRelyingPartyEntityId());
         }
         SAML2AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
 
         if (log.isDebugEnabled()) {
-            log.debug("Resolving principal name for subject of SAML request " + requestContext.getSamlRequest().getID()
-                    + " from relying party " + requestContext.getRelyingPartyId());
+            log.debug("Resolving principal name for subject of SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getRelyingPartyEntityId());
         }
 
         try {
-            String principal = attributeAuthority.getPrincipal(buildAttributeRequestContext(requestContext));
+            String principal = attributeAuthority.getPrincipal(requestContext);
             requestContext.setPrincipalName(principal);
         } catch (AttributeRequestException e) {
-            log.error("Error resolving attributes for SAML request " + requestContext.getSamlRequest().getID()
-                    + " from relying party " + requestContext.getRelyingPartyId(), e);
+            log.error("Error resolving attributes for SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getRelyingPartyEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.UNKNOWN_PRINCIPAL_URI,
                     "Error resolving principal"));
             throw new ProfileException("Error resolving attributes for SAML request "
-                    + requestContext.getSamlRequest().getID() + " from relying party "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getInboundSAMLMessageId() + " from relying party "
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
     /**
-     * Creates an attribute query context from the current profile request context.
-     * 
-     * @param requestContext current profile request
-     * 
-     * @return created query context
-     */
-    protected ShibbolethSAMLAttributeRequestContext<NameID, AttributeQuery> buildAttributeRequestContext(
-            SAML2ProfileRequestContext requestContext) {
-
-        ShibbolethSAMLAttributeRequestContext<NameID, AttributeQuery> queryContext;
-
-        if (requestContext.getSamlRequest() instanceof AttributeQuery) {
-            queryContext = new ShibbolethSAMLAttributeRequestContext<NameID, AttributeQuery>(getMetadataProvider(),
-                    requestContext.getRelyingPartyConfiguration(), (AttributeQuery) requestContext.getSamlRequest());
-        } else {
-            queryContext = new ShibbolethSAMLAttributeRequestContext<NameID, AttributeQuery>(getMetadataProvider(),
-                    requestContext.getRelyingPartyConfiguration(), null);
-        }
-        queryContext.setAttributeRequester(requestContext.getAssertingPartyId());
-        queryContext.setPrincipalName(requestContext.getPrincipalName());
-        queryContext.setProfileConfiguration(requestContext.getProfileConfiguration());
-        queryContext.setRequest(requestContext.getProfileRequest());
-
-        Session userSession = getSessionManager().getSession(getUserSessionId(requestContext.getProfileRequest()));
-        if (userSession != null) {
-            queryContext.setUserSession(userSession);
-            ServiceInformation serviceInfo = userSession.getServicesInformation().get(
-                    requestContext.getRelyingPartyId());
-            if (serviceInfo != null) {
-                String principalAuthenticationMethod = serviceInfo.getAuthenticationMethod().getAuthenticationMethod();
-
-                requestContext.setPrincipalAuthenticationMethod(principalAuthenticationMethod);
-                queryContext.setPrincipalAuthenticationMethod(principalAuthenticationMethod);
-            }
-        }
-
-        return queryContext;
-    }
-
-    /**
      * Signs the given assertion if either the current profile configuration or the relying party configuration contains
      * signing credentials.
      * 
@@ -472,10 +432,10 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * @throws ProfileException thrown if the metadata can not be located for the relying party or, if signing is
      *             required, if a signing credential is not configured
      */
-    protected void signAssertion(SAML2ProfileRequestContext requestContext, Assertion assertion)
+    protected void signAssertion(BaseSAML2ProfileRequestContext<?,?,?> requestContext, Assertion assertion)
             throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Determining if SAML assertion to relying party " + requestContext.getRelyingPartyId()
+            log.debug("Determining if SAML assertion to relying party " + requestContext.getRelyingPartyEntityId()
                     + " should be signed");
         }
 
@@ -488,7 +448,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
             if (ssoDescriptor.getWantAssertionsSigned() != null) {
                 signAssertion = ssoDescriptor.getWantAssertionsSigned().booleanValue();
                 if (log.isDebugEnabled()) {
-                    log.debug("Entity metadata for relying party " + requestContext.getRelyingPartyId()
+                    log.debug("Entity metadata for relying party " + requestContext.getRelyingPartyEntityId()
                             + " indicates to sign assertions: " + signAssertion);
                 }
             }
@@ -505,7 +465,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
 
         if (log.isDebugEnabled()) {
             log.debug("Determining signing credntial for assertion to relying party "
-                    + requestContext.getRelyingPartyId());
+                    + requestContext.getRelyingPartyEntityId());
         }
         Credential signatureCredential = profileConfig.getSigningCredential();
         if (signatureCredential == null) {
@@ -519,7 +479,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
         }
 
         if (log.isDebugEnabled()) {
-            log.debug("Signing assertion to relying party " + requestContext.getRelyingPartyId());
+            log.debug("Signing assertion to relying party " + requestContext.getRelyingPartyEntityId());
         }
         SAMLObjectContentReference contentRef = new SAMLObjectContentReference(assertion);
         Signature signature = signatureBuilder.buildObject(Signature.DEFAULT_ELEMENT_NAME);
@@ -573,16 +533,16 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * @throws ProfileException thrown if a NameID can not be created either because there was a problem encoding the
      *             name ID attribute or because there are no supported name formats
      */
-    protected Subject buildSubject(SAML2ProfileRequestContext requestContext, String confirmationMethod,
+    protected Subject buildSubject(BaseSAML2ProfileRequestContext<?,?,?> requestContext, String confirmationMethod,
             DateTime issueInstant) throws ProfileException {
         NameID nameID = buildNameId(requestContext);
         requestContext.setSubjectNameID(nameID);
         // TODO handle encryption
 
         SubjectConfirmationData confirmationData = subjectConfirmationDataBuilder.buildObject();
-        ProfileRequest<ServletRequest> profileRequest = requestContext.getProfileRequest();
-        confirmationData.setAddress(profileRequest.getRawRequest().getRemoteAddr());
-        confirmationData.setInResponseTo(requestContext.getSamlRequest().getID());
+        HTTPInTransport inTransport = (HTTPInTransport) requestContext.getMessageInTransport();
+        confirmationData.setAddress(inTransport.getPeerAddress());
+        confirmationData.setInResponseTo(requestContext.getInboundSAMLMessageId());
         confirmationData.setNotOnOrAfter(issueInstant.plus(requestContext.getProfileConfiguration()
                 .getAssertionLifetime()));
 
@@ -620,10 +580,10 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * @throws ProfileException thrown if a NameID can not be created either because there was a problem encoding the
      *             name ID attribute or because there are no supported name formats
      */
-    protected NameID buildNameId(SAML2ProfileRequestContext requestContext) throws ProfileException {
+    protected NameID buildNameId(BaseSAML2ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
         if (log.isDebugEnabled()) {
             log.debug("Building assertion NameID for principal/relying party:" + requestContext.getPrincipalName()
-                    + "/" + requestContext.getRelyingPartyId());
+                    + "/" + requestContext.getRelyingPartyEntityId());
         }
         Map<String, BaseAttribute> principalAttributes = requestContext.getPrincipalAttributes();
         List<String> supportedNameFormats = getNameFormats(requestContext);
@@ -676,15 +636,15 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @throws ProfileException thrown if there is a problem determing the NameID format to use
      */
-    protected List<String> getNameFormats(SAML2ProfileRequestContext requestContext) throws ProfileException {
+    protected List<String> getNameFormats(BaseSAML2ProfileRequestContext<?,?,?> requestContext) throws ProfileException {
         ArrayList<String> nameFormats = new ArrayList<String>();
 
         List<String> assertingPartySupportedFormats = getEntitySupportedFormats(requestContext
                 .getAssertingPartyRoleMetadata());
 
         String nameFormat = null;
-        if (requestContext.getSamlRequest() instanceof AuthnRequest) {
-            AuthnRequest authnRequest = (AuthnRequest) requestContext.getSamlRequest();
+        if (requestContext.getInboundSAMLMessage() instanceof AuthnRequest) {
+            AuthnRequest authnRequest = (AuthnRequest) requestContext.getInboundSAMLMessage();
             if (authnRequest.getNameIDPolicy() != null && !DatatypeHelper.isEmpty(nameFormat)) {
                 nameFormat = authnRequest.getNameIDPolicy().getFormat();
                 if (assertingPartySupportedFormats.contains(nameFormat)) {
@@ -748,7 +708,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @return the constructed error response
      */
-    protected Response buildErrorResponse(SAML2ProfileRequestContext requestContext) {
+    protected Response buildErrorResponse(BaseSAML2ProfileRequestContext<?,?,?> requestContext) {
         Response samlResponse = responseBuilder.buildObject();
         samlResponse.setIssueInstant(new DateTime());
         populateStatusResponse(requestContext, samlResponse);
@@ -763,147 +723,20 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
      * 
      * @param context current request context
      */
-    protected void writeAuditLogEntry(SAML2ProfileRequestContext context) {
+    protected void writeAuditLogEntry(BaseSAML2ProfileRequestContext<?,?,?> context) {
         AuditLogEntry auditLogEntry = new AuditLogEntry();
         auditLogEntry.setMessageProfile(getProfileId());
         auditLogEntry.setPrincipalAuthenticationMethod(context.getPrincipalAuthenticationMethod());
         auditLogEntry.setPrincipalName(context.getPrincipalName());
-        auditLogEntry.setAssertingPartyId(context.getAssertingPartyId());
-        auditLogEntry.setRelyingPartyId(context.getRelyingPartyId());
-        auditLogEntry.setRequestBinding(context.getMessageDecoder());
-        auditLogEntry.setRequestId(context.getSamlRequest().getID());
-        auditLogEntry.setResponseBinding(context.getMessageEncoder());
-        auditLogEntry.setResponseId(context.getSamlResponse().getID());
-        if (context.getPrincipalAttributes() != null) {
-            auditLogEntry.getReleasedAttributes().addAll(context.getPrincipalAttributes().keySet());
+        auditLogEntry.setAssertingPartyId(context.getAssertingPartyEntityId());
+        auditLogEntry.setRelyingPartyId(context.getRelyingPartyEntityId());
+        auditLogEntry.setRequestBinding(getMessageDecoder().getBindingURI());
+        auditLogEntry.setRequestId(context.getInboundSAMLMessageId());
+        auditLogEntry.setResponseBinding(getMessageEncoder().getBindingURI());
+        auditLogEntry.setResponseId(context.getOutboundSAMLMessageId());
+        if (context.getReleasedPrincipalAttributeIds() != null) {
+            auditLogEntry.getReleasedAttributes().addAll(context.getReleasedPrincipalAttributeIds());
         }
         getAduitLog().log(Level.CRITICAL, auditLogEntry);
     }
-
-    /**
-     * Contextual object used to accumlate information as profile requests are being processed.
-     * 
-     * @param <RequestType> type of SAML 2 request
-     * @param <ResponseType> type of SAML 2 response
-     * @param <ProfileConfigurationType> configuration type for this profile
-     */
-    protected class SAML2ProfileRequestContext<RequestType extends RequestAbstractType, ResponseType extends StatusResponseType, ProfileConfigurationType extends AbstractSAML2ProfileConfiguration>
-            extends SAMLProfileRequestContext {
-
-        /** SAML request message. */
-        private RequestType samlRequest;
-
-        /** SAML response message. */
-        private ResponseType samlResponse;
-
-        /** Request profile configuration. */
-        private ProfileConfigurationType profileConfiguration;
-
-        /** The NameID of the subject of this request. */
-        private NameID subjectNameID;
-
-        /** The request failure status. */
-        private Status failureStatus;
-
-        /**
-         * Constructor.
-         * 
-         * @param request current profile request
-         * @param response current profile response
-         */
-        public SAML2ProfileRequestContext(ProfileRequest<ServletRequest> request,
-                ProfileResponse<ServletResponse> response) {
-            super(request, response);
-        }
-
-        /**
-         * Gets the NameID of the subject of this request.
-         * 
-         * @return NameID of the subject of this request
-         */
-        public NameID getSubjectNameID() {
-            return subjectNameID;
-        }
-
-        /**
-         * Sets the NameID of the subject of this request.
-         * 
-         * @param nameID NameID of the subject of this request
-         */
-        public void setSubjectNameID(NameID nameID) {
-            subjectNameID = nameID;
-        }
-
-        /**
-         * Gets the profile configuration for this request.
-         * 
-         * @return profile configuration for this request
-         */
-        public ProfileConfigurationType getProfileConfiguration() {
-            return profileConfiguration;
-        }
-
-        /**
-         * Sets the profile configuration for this request.
-         * 
-         * @param configuration profile configuration for this request
-         */
-        public void setProfileConfiguration(ProfileConfigurationType configuration) {
-            profileConfiguration = configuration;
-        }
-
-        /**
-         * Gets the SAML request message.
-         * 
-         * @return SAML request message
-         */
-        public RequestType getSamlRequest() {
-            return samlRequest;
-        }
-
-        /**
-         * Sets the SAML request message.
-         * 
-         * @param request SAML request message
-         */
-        public void setSamlRequest(RequestType request) {
-            samlRequest = request;
-        }
-
-        /**
-         * Gets the SAML response message.
-         * 
-         * @return SAML response message
-         */
-        public ResponseType getSamlResponse() {
-            return samlResponse;
-        }
-
-        /**
-         * Sets the SAML response message.
-         * 
-         * @param response SAML response message
-         */
-        public void setSamlResponse(ResponseType response) {
-            samlResponse = response;
-        }
-
-        /**
-         * Gets the status reflecting a request failure.
-         * 
-         * @return status reflecting a request failure
-         */
-        public Status getFailureStatus() {
-            return failureStatus;
-        }
-
-        /**
-         * Sets the status reflecting a request failure.
-         * 
-         * @param status status reflecting a request failure
-         */
-        public void setFailureStatus(Status status) {
-            failureStatus = status;
-        }
-    }
 }
\ No newline at end of file
index 1d9a998..3832774 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.profile.saml2;
 
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
 
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 
 /**
  * SAML 2.0 Artifact resolution profile handler.
@@ -29,15 +27,14 @@ import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 public class ArtifactResolution extends AbstractSAML2ProfileHandler {
 
     /** {@inheritDoc} */
-    public String getProfileId() {
+    public void processRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport) throws ProfileException {
         // TODO Auto-generated method stub
-        return null;
+
     }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
-            throws ProfileException {
+    public String getProfileId() {
         // TODO Auto-generated method stub
-
+        return null;
     }
 }
\ No newline at end of file
index f214e89..52d3cd9 100644 (file)
@@ -18,26 +18,23 @@ package edu.internet2.middleware.shibboleth.idp.profile.saml2;
 
 import java.util.ArrayList;
 
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
 import org.apache.log4j.Logger;
-import org.opensaml.common.binding.BindingException;
-import org.opensaml.common.binding.decoding.MessageDecoder;
-import org.opensaml.common.binding.encoding.MessageEncoder;
-import org.opensaml.common.binding.security.SAMLSecurityPolicy;
 import org.opensaml.common.xml.SAMLConstants;
-import org.opensaml.saml2.binding.decoding.HTTPSOAP11Decoder;
 import org.opensaml.saml2.core.AttributeQuery;
 import org.opensaml.saml2.core.Response;
 import org.opensaml.saml2.core.Statement;
 import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.metadata.AttributeAuthorityDescriptor;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.ws.message.decoder.MessageDecodingException;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
 import org.opensaml.ws.security.SecurityPolicyException;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
 
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml2.AttributeQueryConfiguration;
 
@@ -47,30 +44,24 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
     /** Class logger. */
     private static Logger log = Logger.getLogger(AttributeQueryProfileHandler.class);
 
-    /** SAML binding URI. */
-    private static final String BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:SOAP";
-
     /** {@inheritDoc} */
     public String getProfileId() {
         return "urn:mace:shibboleth:2.0:idp:profiles:saml2:query:attribute";
     }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
-            throws ProfileException {
+    public void processRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport) throws ProfileException {
+        Response samlResponse;
 
-        AttributeQueryContext requestContext = new AttributeQueryContext(request, response);
+        AttributeQueryContext requestContext = decodeRequest(inTransport, outTransport);
 
-        Response samlResponse;
         try {
-            decodeRequest(requestContext);
-            
             if (requestContext.getRelyingPartyConfiguration() == null) {
                 log.error("SAML 2 Attribute Query profile is not configured for relying party "
-                        + requestContext.getRelyingPartyId());
+                        + requestContext.getRelyingPartyEntityId());
                 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.REQUEST_DENIED_URI,
                         "SAML 2 Attribute Query profile is not configured for relying party "
-                                + requestContext.getRelyingPartyId()));
+                                + requestContext.getRelyingPartyEntityId()));
                 samlResponse = buildErrorResponse(requestContext);
             }
 
@@ -78,7 +69,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
 
             // Resolve attribute query name id to principal name and place in context
             resolvePrincipal(requestContext);
-            
+
             resolveAttributes(requestContext);
 
             // Lookup principal name and attributes, create attribute statement from information
@@ -91,41 +82,46 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
             samlResponse = buildErrorResponse(requestContext);
         }
 
-        requestContext.setSamlResponse(samlResponse);
+        requestContext.setOutboundSAMLMessage(samlResponse);
+        requestContext.setOutboundSAMLMessageId(samlResponse.getID());
+        requestContext.setOutboundSAMLMessageIssueInstant(samlResponse.getIssueInstant());
 
         encodeResponse(requestContext);
         writeAuditLogEntry(requestContext);
     }
 
     /**
-     * Decodes the message in the request and adds it to the request context.
+     * Decodes an incoming request and populates a created request context with the resultant information.
+     * 
+     * @param inTransport inbound message transport
+     * @param outTransport outbound message transport
      * 
-     * @param requestContext request context contianing the request to decode
+     * @return the created request context
      * 
      * @throws ProfileException throw if there is a problem decoding the request
      */
-    protected void decodeRequest(AttributeQueryContext requestContext) throws ProfileException {
+    protected AttributeQueryContext decodeRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport)
+            throws ProfileException {
         if (log.isDebugEnabled()) {
             log.debug("Decoding incomming request");
         }
-        MessageDecoder<ServletRequest> decoder = getMessageDecoderFactory().getMessageDecoder(
-                HTTPSOAP11Decoder.BINDING_URI);
-        if (decoder == null) {
-            throw new ProfileException("No request decoder was registered for binding type: "
-                    + HTTPSOAP11Decoder.BINDING_URI);
-        }
-        super.populateMessageDecoder(decoder);
 
-        ProfileRequest<ServletRequest> profileRequest = requestContext.getProfileRequest(); 
-        decoder.setRequest(profileRequest.getRawRequest());
-        requestContext.setMessageDecoder(decoder.getBindingURI());
+        MetadataProvider metadataProvider = getMetadataProvider();
+
+        AttributeQueryContext requestContext = new AttributeQueryContext();
+        requestContext.setMessageInTransport(inTransport);
+        requestContext.setInboundSAMLProtocol(SAMLConstants.SAML20P_NS);
+        requestContext.setMessageOutTransport(outTransport);
+        requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML20P_NS);
+        requestContext.setMetadataProvider(metadataProvider);
 
         try {
-            decoder.decode();
+            getMessageDecoder().decode(requestContext);
             if (log.isDebugEnabled()) {
                 log.debug("Decoded request");
             }
-        } catch (BindingException e) {
+            return requestContext;
+        } catch (MessageDecodingException e) {
             log.error("Error decoding attribute query message", e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, null, "Error decoding message"));
             throw new ProfileException("Error decoding attribute query message");
@@ -136,31 +132,35 @@ 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 = decoder.getSecurityPolicy();
-            requestContext.setRelyingPartyId(securityPolicy.getIssuer());
-
             try {
-                requestContext.setRelyingPartyMetadata(getMetadataProvider().getEntityDescriptor(
-                        requestContext.getRelyingPartyId()));
+                AttributeQuery attributeQuery = requestContext.getInboundSAMLMessage();
+                requestContext.setInboundSAMLMessageId(attributeQuery.getID());
+                requestContext.setInboundSAMLMessageIssueInstant(attributeQuery.getIssueInstant());
 
+                String relyingPartyId = requestContext.getRelyingPartyEntityId();
+                requestContext.setRelyingPartyMetadata(metadataProvider.getEntityDescriptor(relyingPartyId));
+                requestContext.setRelyingPartyRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
                 requestContext.setRelyingPartyRoleMetadata(requestContext.getRelyingPartyMetadata().getSPSSODescriptor(
                         SAMLConstants.SAML20P_NS));
-
-                RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(requestContext.getRelyingPartyId());
+                RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
                 requestContext.setRelyingPartyConfiguration(rpConfig);
 
-                requestContext.setAssertingPartyId(requestContext.getRelyingPartyConfiguration().getProviderId());
-
-                requestContext.setAssertingPartyMetadata(getMetadataProvider().getEntityDescriptor(
-                        requestContext.getAssertingPartyId()));
-
+                String assertingPartyId = requestContext.getRelyingPartyConfiguration().getProviderId();
+                requestContext.setAssertingPartyEntityId(assertingPartyId);
+                requestContext.setAssertingPartyMetadata(metadataProvider.getEntityDescriptor(assertingPartyId));
+                requestContext.setAssertingPartyRole(AttributeAuthorityDescriptor.DEFAULT_ELEMENT_NAME);
                 requestContext.setAssertingPartyRoleMetadata(requestContext.getAssertingPartyMetadata()
                         .getAttributeAuthorityDescriptor(SAMLConstants.SAML20P_NS));
 
-                requestContext.setProfileConfiguration((AttributeQueryConfiguration) rpConfig
-                        .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID));
+                AttributeQueryConfiguration profileConfig = (AttributeQueryConfiguration) rpConfig
+                        .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID);
+                requestContext.setProfileConfiguration(profileConfig);
+                if (profileConfig.getSigningCredential() != null) {
+                    requestContext.setOutboundSAMLMessageSigningCredential(profileConfig.getSigningCredential());
+                } else if (rpConfig.getDefaultSigningCredential() != null) {
+                    requestContext.setOutboundSAMLMessageSigningCredential(rpConfig.getDefaultSigningCredential());
+                }
 
-                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,
@@ -179,41 +179,21 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
      */
     protected void encodeResponse(AttributeQueryContext requestContext) throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request " + requestContext.getSamlRequest().getID()
-                    + " from relying party " + requestContext.getRelyingPartyId());
+            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getRelyingPartyEntityId());
         }
-        MessageEncoder<ServletResponse> encoder = getMessageEncoderFactory().getMessageEncoder(BINDING);
-        if (encoder == null) {
-            throw new ProfileException("No response encoder was registered for binding type: " + BINDING);
-        }
-
-        super.populateMessageEncoder(encoder);
-        encoder.setRelayState(requestContext.getRelayState());
-        ProfileResponse<ServletResponse> profileResponse = requestContext.getProfileResponse();
-        encoder.setResponse(profileResponse.getRawResponse());
-        encoder.setSamlMessage(requestContext.getSamlResponse());
-        requestContext.setMessageEncoder(encoder.getBindingURI());
 
         try {
-            encoder.encode();
-        } catch (BindingException e) {
+            getMessageEncoder().encode(requestContext);
+        } catch (MessageEncodingException e) {
             throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
     /** Basic data structure used to accumulate information as a request is being processed. */
     protected class AttributeQueryContext extends
-            SAML2ProfileRequestContext<AttributeQuery, Response, AttributeQueryConfiguration> {
-
-        /**
-         * Constructor.
-         * 
-         * @param request current profile request
-         * @param response current profile response
-         */
-        public AttributeQueryContext(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response) {
-            super(request, response);
-        }
+            BaseSAML2ProfileRequestContext<AttributeQuery, Response, AttributeQueryConfiguration> {
+
     }
 }
\ No newline at end of file
diff --git a/src/edu/internet2/middleware/shibboleth/idp/profile/saml2/BaseSAML2ProfileRequestContext.java b/src/edu/internet2/middleware/shibboleth/idp/profile/saml2/BaseSAML2ProfileRequestContext.java
new file mode 100644 (file)
index 0000000..2ff6582
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.internet2.middleware.shibboleth.idp.profile.saml2;
+
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.RequestAbstractType;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusResponseType;
+
+import edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAMLAttributeRequestContext;
+import edu.internet2.middleware.shibboleth.common.profile.provider.BaseShibbolethProfileRequestContext;
+import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml2.AbstractSAML2ProfileConfiguration;
+
+/**
+ * Contextual object used to accumlate information as profile requests are being processed.
+ * 
+ * @param <RequestType> type of SAML 2 request
+ * @param <ResponseType> type of SAML 2 response
+ * @param <ProfileConfigurationType> configuration type for this profile
+ */
+public abstract class BaseSAML2ProfileRequestContext<RequestType extends RequestAbstractType, ResponseType extends StatusResponseType, ProfileConfigurationType extends AbstractSAML2ProfileConfiguration>
+        extends BaseShibbolethProfileRequestContext<RequestType, ResponseType, ProfileConfigurationType> 
+        implements ShibbolethSAMLAttributeRequestContext<NameID, RequestType, ResponseType, ProfileConfigurationType> {
+
+    /** The request failure status. */
+    private Status failureStatus;
+
+    /**
+     * Gets the status reflecting a request failure.
+     * 
+     * @return status reflecting a request failure
+     */
+    public Status getFailureStatus() {
+        return failureStatus;
+    }
+
+    /**
+     * Sets the status reflecting a request failure.
+     * 
+     * @param status status reflecting a request failure
+     */
+    public void setFailureStatus(Status status) {
+        failureStatus = status;
+    }
+}
\ No newline at end of file
index bdf4e8a..2a3dc2a 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.profile.saml2;
 
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
+
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 
 /**
  * SAML 2.0 Logout Request profile handler.
  */
-public abstract class LogoutRequest extends AbstractSAML2ProfileHandler {
+public class LogoutRequest extends AbstractSAML2ProfileHandler {
+
+    /** {@inheritDoc} */
+    public void processRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport) throws ProfileException {
+        // TODO Auto-generated method stub
+
+    }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest request, ProfileResponse response) throws ProfileException {
+    public String getProfileId() {
         // TODO Auto-generated method stub
+        return null;
     }
 }
\ No newline at end of file
index daae537..64891b2 100644 (file)
@@ -22,17 +22,11 @@ import java.util.List;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 
 import org.apache.log4j.Logger;
 import org.opensaml.common.SAMLObjectBuilder;
-import org.opensaml.common.binding.BindingException;
-import org.opensaml.common.binding.decoding.MessageDecoder;
-import org.opensaml.common.binding.encoding.MessageEncoder;
-import org.opensaml.common.binding.security.SAMLSecurityPolicy;
 import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml2.binding.AuthnResponseEndpointSelector;
 import org.opensaml.saml2.core.AuthnContext;
@@ -47,14 +41,22 @@ import org.opensaml.saml2.core.StatusCode;
 import org.opensaml.saml2.core.SubjectLocality;
 import org.opensaml.saml2.metadata.AssertionConsumerService;
 import org.opensaml.saml2.metadata.Endpoint;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.IDPSSODescriptor;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.ws.message.decoder.MessageDecodingException;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
 import org.opensaml.ws.security.SecurityPolicyException;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+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.UnmarshallingException;
 
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml2.SSOConfiguration;
 import edu.internet2.middleware.shibboleth.common.util.HttpHelper;
@@ -84,7 +86,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
 
     /** URL of the authentication manager servlet. */
     private String authenticationManagerPath;
-    
+
     /** URI of SAML 2 bindings supported for outgoing messaged encoding. */
     private ArrayList<String> supportedOutgoingBindings;
 
@@ -106,12 +108,12 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             throw new IllegalArgumentException("AuthN manager path or decoding bindings URI may not be null");
         }
         authenticationManagerPath = authnManagerPath;
-        
-        if(outgoingBindings == null || outgoingBindings.isEmpty()){
+
+        if (outgoingBindings == null || outgoingBindings.isEmpty()) {
             throw new IllegalArgumentException("List of supported outgoing bindings may not be empty");
         }
         supportedOutgoingBindings = new ArrayList<String>(outgoingBindings);
-        
+
         decodingBinding = decoder;
 
         authnStatementBuilder = (SAMLObjectBuilder<AuthnStatement>) getBuilderFactory().getBuilder(
@@ -132,14 +134,14 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
     }
 
     /** {@inheritDoc} */
-    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
-            throws ProfileException {
+    public void processRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport) throws ProfileException {
+        HttpServletRequest servletRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
+        HttpSession httpSession = servletRequest.getSession();
 
-        HttpSession httpSession = ((HttpServletRequest) request.getRawRequest()).getSession(true);
         if (httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY) == null) {
-            performAuthentication(request, response);
+            performAuthentication(inTransport, outTransport);
         } else {
-            completeAuthenticationRequest(request, response);
+            completeAuthenticationRequest(inTransport, outTransport);
         }
     }
 
@@ -147,52 +149,47 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
      * Creates a {@link Saml2LoginContext} an sends the request off to the AuthenticationManager to begin the process of
      * authenticating the user.
      * 
-     * @param request current request
-     * @param response current response
+     * @param inTransport inbound request transport
+     * @param outTransport outbound response transport
      * 
      * @throws ProfileException thrown if there is a problem creating the login context and transferring control to the
      *             authentication manager
      */
-    protected void performAuthentication(ProfileRequest<ServletRequest> request,
-            ProfileResponse<ServletResponse> response) throws ProfileException {
-        HttpServletRequest httpRequest = (HttpServletRequest) request.getRawRequest();
+    protected void performAuthentication(HTTPInTransport inTransport, HTTPOutTransport outTransport)
+            throws ProfileException {
+        HttpServletRequest servletRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
 
-        AuthnRequest authnRequest = null;
         try {
-            MessageDecoder<ServletRequest> decoder = decodeRequest(request);
-            SAMLSecurityPolicy securityPolicy = decoder.getSecurityPolicy();
+            SSORequestContext requestContext = decodeRequest(inTransport, outTransport);
 
-            String relyingParty = securityPolicy.getIssuer();
-            RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingParty);
+            String relyingPartyId = requestContext.getRelyingPartyEntityId();
+            RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
             if (rpConfig == null) {
-                log.error("No relying party configuration for " + relyingParty);
-                throw new ProfileException("No relying party configuration for " + relyingParty);
+                log.error("No relying party configuration for " + relyingPartyId);
+                throw new ProfileException("No relying party configuration for " + relyingPartyId);
             }
 
-            authnRequest = (AuthnRequest) decoder.getSAMLMessage();
-
-            Saml2LoginContext loginContext = new Saml2LoginContext(relyingParty, decoder.getRelayState(), authnRequest);
+            Saml2LoginContext loginContext = new Saml2LoginContext(relyingPartyId, requestContext.getRelayState(),
+                    requestContext.getInboundSAMLMessage());
             loginContext.setAuthenticationEngineURL(authenticationManagerPath);
-            loginContext.setProfileHandlerURL(HttpHelper.getRequestUriWithoutContext(httpRequest));
+            loginContext.setProfileHandlerURL(HttpHelper.getRequestUriWithoutContext(servletRequest));
             if (loginContext.getRequestedAuthenticationMethods().size() == 0) {
                 loginContext.getRequestedAuthenticationMethods().add(rpConfig.getDefaultAuthenticationMethod());
             }
 
-            HttpSession httpSession = httpRequest.getSession();
+            HttpSession httpSession = servletRequest.getSession();
             httpSession.setAttribute(Saml2LoginContext.LOGIN_CONTEXT_KEY, loginContext);
-            RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(authenticationManagerPath);
-            dispatcher.forward(httpRequest, response.getRawResponse());
+            RequestDispatcher dispatcher = servletRequest.getRequestDispatcher(authenticationManagerPath);
+            dispatcher.forward(servletRequest, ((HttpServletResponseAdapter) outTransport).getWrappedResponse());
         } catch (MarshallingException e) {
             log.error("Unable to marshall authentication request context");
             throw new ProfileException("Unable to marshall authentication request context", e);
         } catch (IOException ex) {
-            log.error("Error forwarding SAML 2 AuthnRequest " + authnRequest.getID() + " to AuthenticationManager", ex);
-            throw new ProfileException("Error forwarding SAML 2 AuthnRequest " + authnRequest.getID()
-                    + " to AuthenticationManager", ex);
+            log.error("Error forwarding SAML 2 AuthnRequest to AuthenticationManager", ex);
+            throw new ProfileException("Error forwarding SAML 2 AuthnRequest to AuthenticationManager", ex);
         } catch (ServletException ex) {
-            log.error("Error forwarding SAML 2 AuthnRequest " + authnRequest.getID() + " to AuthenticationManager", ex);
-            throw new ProfileException("Error forwarding SAML 2 AuthnRequest " + authnRequest.getID()
-                    + " to AuthenticationManager", ex);
+            log.error("Error forwarding SAML 2 AuthnRequest to AuthenticationManager", ex);
+            throw new ProfileException("Error forwarding SAML 2 AuthnRequest to AuthenticationManager", ex);
         }
     }
 
@@ -200,20 +197,20 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
      * Creates a response to the {@link AuthnRequest} and sends the user, with response in tow, back to the relying
      * party after they've been authenticated.
      * 
-     * @param request current request
-     * @param response current response
+     * @param inTransport inbound message transport
+     * @param outTransport outbound message transport
      * 
      * @throws ProfileException thrown if the response can not be created and sent back to the relying party
      */
-    protected void completeAuthenticationRequest(ProfileRequest<ServletRequest> request,
-            ProfileResponse<ServletResponse> response) throws ProfileException {
-
-        HttpSession httpSession = ((HttpServletRequest) request.getRawRequest()).getSession(true);
+    protected void completeAuthenticationRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport)
+            throws ProfileException {
+        HttpServletRequest servletRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
+        HttpSession httpSession = servletRequest.getSession();
 
         Saml2LoginContext loginContext = (Saml2LoginContext) httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
         httpSession.removeAttribute(LoginContext.LOGIN_CONTEXT_KEY);
 
-        SSORequestContext requestContext = buildRequestContext(loginContext, request, response);
+        SSORequestContext requestContext = buildRequestContext(loginContext, inTransport, outTransport);
 
         checkSamlVersion(requestContext);
 
@@ -225,12 +222,12 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
                         .setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.AUTHN_FAILED_URI, null));
                 throw new ProfileException("User failed authentication");
             }
-            
+
             resolveAttributes(requestContext);
-            
+
             ArrayList<Statement> statements = new ArrayList<Statement>();
             statements.add(buildAuthnStatement(requestContext));
-            if(requestContext.getProfileConfiguration().includeAttributeStatement()){
+            if (requestContext.getProfileConfiguration().includeAttributeStatement()) {
                 statements.add(buildAttributeStatement(requestContext));
             }
 
@@ -239,37 +236,38 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             samlResponse = buildErrorResponse(requestContext);
         }
 
-        requestContext.setSamlResponse(samlResponse);
+        requestContext.setOutboundSAMLMessage(samlResponse);
+        requestContext.setOutboundSAMLMessageId(samlResponse.getID());
+        requestContext.setOutboundSAMLMessageIssueInstant(samlResponse.getIssueInstant());
         encodeResponse(requestContext);
         writeAuditLogEntry(requestContext);
     }
 
     /**
-     * Creates an appropriate message decoder, populates it, and decodes the incoming request.
+     * Decodes an incoming request and stores the information in a created request context.
      * 
-     * @param request current request
+     * @param inTransport inbound transport
+     * @param outTransport outbound transport
      * 
-     * @return message decoder containing the decoded message and other stateful information
+     * @return request context with decoded information
      * 
      * @throws ProfileException thrown if the incomming message failed decoding
      */
-    protected MessageDecoder<ServletRequest> decodeRequest(ProfileRequest<ServletRequest> request)
+    protected SSORequestContext decodeRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport)
             throws ProfileException {
-        if(log.isDebugEnabled()){
+        if (log.isDebugEnabled()) {
             log.debug("Decoding message with decoder binding " + decodingBinding);
         }
-        MessageDecoder<ServletRequest> decoder = getMessageDecoderFactory().getMessageDecoder(decodingBinding);
-        if (decoder == null) {
-            log.error("No request decoder was registered for binding type: " + decodingBinding);
-            throw new ProfileException("No request decoder was registered for binding type: " + decodingBinding);
-        }
 
-        populateMessageDecoder(decoder);
-        decoder.setRequest(request.getRawRequest());
+        SSORequestContext requestContext = new SSORequestContext();
+        requestContext.setMessageInTransport(inTransport);
+        requestContext.setMessageOutTransport(outTransport);
+        requestContext.setMetadataProvider(getMetadataProvider());
+
         try {
-            decoder.decode();
-            return decoder;
-        } catch (BindingException e) {
+            getMessageDecoder().decode(requestContext);
+            return requestContext;
+        } catch (MessageDecodingException e) {
             log.error("Error decoding authentication request message", e);
             throw new ProfileException("Error decoding authentication request message", e);
         } catch (SecurityPolicyException e) {
@@ -282,53 +280,62 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
      * Creates an authentication request context from the current environmental information.
      * 
      * @param loginContext current login context
-     * @param request current request
-     * @param response current response
+     * @param in inbound transport
+     * @param out outbount transport
      * 
      * @return created authentication request context
      * 
      * @throws ProfileException thrown if there is a problem creating the context
      */
-    protected SSORequestContext buildRequestContext(Saml2LoginContext loginContext,
-            ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response) throws ProfileException {
-        SSORequestContext requestContext = new SSORequestContext(request, response);
+    protected SSORequestContext buildRequestContext(Saml2LoginContext loginContext, HTTPInTransport in,
+            HTTPOutTransport out) throws ProfileException {
+        SSORequestContext requestContext = new SSORequestContext();
 
         try {
-            requestContext.setMessageDecoder(decodingBinding);
-
-            requestContext.setRelayState(loginContext.getRelayState());
-
             requestContext.setLoginContext(loginContext);
+            requestContext.setPrincipalName(loginContext.getPrincipalName());
+            requestContext.setPrincipalAuthenticationMethod(loginContext.getAuthenticationMethod());
+            requestContext.setUserSession(getUserSession(in));
+            requestContext.setRelayState(loginContext.getRelayState());
 
-            String relyingPartyId = loginContext.getRelyingPartyId();
-            AuthnRequest authnRequest = loginContext.getAuthenticationRequest();
-
-            requestContext.setRelyingPartyId(relyingPartyId);
-
-            requestContext.setRelyingPartyMetadata(getMetadataProvider().getEntityDescriptor(relyingPartyId));
+            requestContext.setMessageInTransport(in);
+            requestContext.setInboundSAMLProtocol(SAMLConstants.SAML20P_NS);
+            requestContext.setInboundMessage(loginContext.getAuthenticationRequest());
+            requestContext.setInboundSAMLMessage(loginContext.getAuthenticationRequest());
+            requestContext.setInboundSAMLMessageId(loginContext.getAuthenticationRequest().getID());
 
-            requestContext.setRelyingPartyRoleMetadata(requestContext.getRelyingPartyMetadata().getSPSSODescriptor(
-                    SAMLConstants.SAML20P_NS));
+            MetadataProvider metadataProvider = getMetadataProvider();
+            requestContext.setMetadataProvider(metadataProvider);
 
+            String relyingPartyId = loginContext.getRelyingPartyId();
+            requestContext.setRelyingPartyEntityId(relyingPartyId);
+            EntityDescriptor relyingPartyMetadata = metadataProvider.getEntityDescriptor(relyingPartyId);
+            requestContext.setRelyingPartyMetadata(relyingPartyMetadata);
+            requestContext.setRelyingPartyRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+            requestContext.setRelyingPartyRoleMetadata(relyingPartyMetadata
+                    .getSPSSODescriptor(SAMLConstants.SAML20P_NS));
             RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
             requestContext.setRelyingPartyConfiguration(rpConfig);
-
-            requestContext.setAssertingPartyId(requestContext.getRelyingPartyConfiguration().getProviderId());
-
-            requestContext.setAssertingPartyMetadata(getMetadataProvider().getEntityDescriptor(
-                    requestContext.getAssertingPartyId()));
-
-            requestContext.setAssertingPartyRoleMetadata(requestContext.getRelyingPartyMetadata().getIDPSSODescriptor(
-                    SAMLConstants.SAML20P_NS));
-
-            requestContext.setPrincipalName(loginContext.getPrincipalName());
-
-            requestContext.setProfileConfiguration((SSOConfiguration) rpConfig
-                    .getProfileConfiguration(SSOConfiguration.PROFILE_ID));
-
-            requestContext.setSamlRequest(authnRequest);
-            
-            selectEndpoint(requestContext);
+            requestContext.setRelyingPartyEndpoint(selectEndpoint(requestContext));
+
+            String assertingPartyId = rpConfig.getProviderId();
+            requestContext.setAssertingPartyEntityId(assertingPartyId);
+            EntityDescriptor assertingPartyMetadata = metadataProvider.getEntityDescriptor(assertingPartyId);
+            requestContext.setAssertingPartyMetadata(assertingPartyMetadata);
+            requestContext.setAssertingPartyRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
+            requestContext.setAssertingPartyRoleMetadata(assertingPartyMetadata
+                    .getIDPSSODescriptor(SAMLConstants.SAML20P_NS));
+
+            requestContext.setMessageOutTransport(out);
+            requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML20P_NS);
+            SSOConfiguration profileConfig = (SSOConfiguration) rpConfig
+                    .getProfileConfiguration(SSOConfiguration.PROFILE_ID);
+            requestContext.setProfileConfiguration(profileConfig);
+            if (profileConfig.getSigningCredential() != null) {
+                requestContext.setOutboundSAMLMessageSigningCredential(profileConfig.getSigningCredential());
+            } else if (rpConfig.getDefaultSigningCredential() != null) {
+                requestContext.setOutboundSAMLMessageSigningCredential(rpConfig.getDefaultSigningCredential());
+            }
 
             return requestContext;
         } catch (UnmarshallingException e) {
@@ -384,7 +391,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         AuthnContext authnContext = authnContextBuilder.buildObject();
 
         Saml2LoginContext loginContext = requestContext.getLoginContext();
-        AuthnRequest authnRequest = requestContext.getSamlRequest();
+        AuthnRequest authnRequest = requestContext.getInboundSAMLMessage();
         RequestedAuthnContext requestedAuthnContext = authnRequest.getRequestedAuthnContext();
         if (requestedAuthnContext != null) {
             if (requestedAuthnContext.getAuthnContextClassRefs() != null) {
@@ -421,29 +428,30 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
      * @return subject locality for the authentication statement
      */
     protected SubjectLocality buildSubjectLocality(SSORequestContext requestContext) {
+        HTTPInTransport transport = (HTTPInTransport) requestContext.getMessageInTransport();
         SubjectLocality subjectLocality = subjectLocalityBuilder.buildObject();
-
-        HttpServletRequest httpRequest = (HttpServletRequest) requestContext.getProfileRequest().getRawRequest();
-        subjectLocality.setAddress(httpRequest.getRemoteAddr());
-        subjectLocality.setDNSName(httpRequest.getRemoteHost());
+        subjectLocality.setAddress(transport.getPeerAddress());
+        subjectLocality.setDNSName(transport.getPeerDomainName());
 
         return subjectLocality;
     }
-    
+
     /**
      * Selects the appropriate endpoint for the relying party and stores it in the request context.
      * 
      * @param requestContext current request context
+     * 
+     * @return Endpoint selected from the information provided in the request context
      */
-    protected void selectEndpoint(SSORequestContext requestContext){
+    protected Endpoint selectEndpoint(SSORequestContext requestContext) {
         AuthnResponseEndpointSelector endpointSelector = new AuthnResponseEndpointSelector();
         endpointSelector.setEndpointType(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
         endpointSelector.setMetadataProvider(getMetadataProvider());
         endpointSelector.setRelyingParty(requestContext.getRelyingPartyMetadata());
         endpointSelector.setRelyingPartyRole(requestContext.getRelyingPartyRoleMetadata());
-        endpointSelector.setSamlRequest(requestContext.getSamlRequest());
+        endpointSelector.setSamlRequest(requestContext.getInboundSAMLMessage());
         endpointSelector.getSupportedIssuerBindings().addAll(supportedOutgoingBindings);
-        requestContext.setRelyingPartyEndpoint(endpointSelector.selectEndpoint());
+        return endpointSelector.selectEndpoint();
     }
 
     /**
@@ -455,55 +463,25 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
      */
     protected void encodeResponse(SSORequestContext requestContext) throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request " + requestContext.getSamlRequest().getID()
-                    + " from relying party " + requestContext.getRelyingPartyId());
+            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getRelyingPartyEntityId());
         }
 
-        Endpoint relyingPartyEndpoint = requestContext.getRelyingPartyEndpoint();
-        MessageEncoder<ServletResponse> encoder = getMessageEncoderFactory().getMessageEncoder(
-                relyingPartyEndpoint.getBinding());
-        if (encoder == null) {
-            log.error("No response encoder was registered for binding type: " + relyingPartyEndpoint.getBinding());
-            throw new ProfileException("No response encoder was registered for binding type: "
-                    + relyingPartyEndpoint.getBinding());
-        }
-
-        super.populateMessageEncoder(encoder);
-        encoder.setIssuer(requestContext.getAssertingPartyId());
-        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.getBindingURI());
-
         try {
-            encoder.encode();
-        } catch (BindingException e) {
+            getMessageEncoder().encode(requestContext);
+        } catch (MessageEncodingException e) {
             throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyId(), e);
+                    + requestContext.getRelyingPartyEntityId(), e);
         }
     }
 
     /** Represents the internal state of a SAML 2.0 SSO Request while it's being processed by the IdP. */
-    protected class SSORequestContext extends SAML2ProfileRequestContext<AuthnRequest, Response, SSOConfiguration> {
+    protected class SSORequestContext extends BaseSAML2ProfileRequestContext<AuthnRequest, Response, SSOConfiguration> {
 
         /** Current login context. */
         private Saml2LoginContext loginContext;
 
         /**
-         * Constructor.
-         * 
-         * @param request current profile request
-         * @param response current profile response
-         */
-        public SSORequestContext(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response) {
-            super(request, response);
-        }
-
-        /**
          * Gets the current login context.
          * 
          * @return current login context