Set communication profile before decoding
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / idp / profile / saml2 / SSOProfileHandler.java
index 257a268..0a0aea6 100644 (file)
@@ -88,6 +88,9 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
     /** Builder of SubjectLocality objects. */
     private SAMLObjectBuilder<SubjectLocality> subjectLocalityBuilder;
 
+    /** Builder of Endpoint objects. */
+    private SAMLObjectBuilder<Endpoint> endpointBuilder;
+
     /** URL of the authentication manager servlet. */
     private String authenticationManagerPath;
 
@@ -112,6 +115,8 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
                 AuthnContextDeclRef.DEFAULT_ELEMENT_NAME);
         subjectLocalityBuilder = (SAMLObjectBuilder<SubjectLocality>) getBuilderFactory().getBuilder(
                 SubjectLocality.DEFAULT_ELEMENT_NAME);
+        endpointBuilder = (SAMLObjectBuilder<Endpoint>) getBuilderFactory().getBuilder(
+                AssertionConsumerService.DEFAULT_ELEMENT_NAME);
     }
 
     /** {@inheritDoc} */
@@ -273,6 +278,8 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             throws ProfileException {
         log.debug("Decoding message with decoder binding {}", getInboundBinding());
         SSORequestContext requestContext = new SSORequestContext();
+        requestContext.setCommunicationProfileId(getProfileId());
+        
         requestContext.setMetadataProvider(getMetadataProvider());
         requestContext.setSecurityPolicyResolver(getSecurityPolicyResolver());
 
@@ -322,6 +329,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
     protected SSORequestContext buildRequestContext(Saml2LoginContext loginContext, HTTPInTransport in,
             HTTPOutTransport out) throws ProfileException {
         SSORequestContext requestContext = new SSORequestContext();
+        requestContext.setCommunicationProfileId(getProfileId());
 
         requestContext.setMessageDecoder(getMessageDecoders().get(getInboundBinding()));
 
@@ -336,11 +344,10 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         requestContext.setMetadataProvider(getMetadataProvider());
 
         String relyingPartyId = loginContext.getRelyingPartyId();
+        requestContext.setPeerEntityId(relyingPartyId);
         requestContext.setInboundMessageIssuer(relyingPartyId);
 
-        populateSAMLMessageInformation(requestContext);
         populateRequestContext(requestContext);
-        populateProfileInformation(requestContext);
 
         return requestContext;
     }
@@ -499,6 +506,8 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
      * @return Endpoint selected from the information provided in the request context
      */
     protected Endpoint selectEndpoint(BaseSAMLProfileRequestContext requestContext) {
+        AuthnRequest authnRequest = ((SSORequestContext) requestContext).getInboundSAMLMessage();
+
         AuthnResponseEndpointSelector endpointSelector = new AuthnResponseEndpointSelector();
         endpointSelector.setEndpointType(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
         endpointSelector.setMetadataProvider(getMetadataProvider());
@@ -506,7 +515,21 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         endpointSelector.setEntityRoleMetadata(requestContext.getPeerEntityRoleMetadata());
         endpointSelector.setSamlRequest(requestContext.getInboundSAMLMessage());
         endpointSelector.getSupportedIssuerBindings().addAll(getSupportedOutboundBindings());
-        return endpointSelector.selectEndpoint();
+
+        Endpoint endpoint = endpointSelector.selectEndpoint();
+        if (endpoint == null && authnRequest.getAssertionConsumerServiceURL() != null) {
+            endpoint = endpointBuilder.buildObject();
+            endpoint.setLocation(authnRequest.getAssertionConsumerServiceURL());
+            if (authnRequest.getProtocolBinding() != null) {
+                endpoint.setBinding(authnRequest.getProtocolBinding());
+            } else {
+                endpoint.setBinding(getSupportedOutboundBindings().get(0));
+            }
+            log.warn("No endpoint available for relying party {}. Generating endpoint with ACS url {} and binding {}",
+                    new Object[] { requestContext.getPeerEntityId(), endpoint.getLocation(), endpoint.getBinding() });
+        }
+
+        return endpoint;
     }
 
     /** Represents the internal state of a SAML 2.0 SSO Request while it's being processed by the IdP. */