title: Spring SAML Alias is used both for entity and SP
body: <p>I am new to SAML, and am integrating it into a Spring web application. I started by following the Spring SAML quick-start guide found here:
     <a href="http://docs.spring.io/spring-security-saml/docs/1.0.0.RELEASE/reference/html/chapter-quick-start.html" rel="nofollow">http://docs.spring.io/spring-security-saml/docs/1.0.0.RELEASE/reference/html/chapter-quick-start.html</a></p>
  
  <p>I got a this running fine. I then wanted to switch to target IDP, which is already running and successfully serving other SPs within the company.  </p>
  
  <p>In my securityContext.xml, I added the following to the metadata bean:</p>
  
  <pre><code>    &lt;bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate"&gt;
          &lt;constructor-arg&gt;
              &lt;bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider"&gt;
                  &lt;constructor-arg&gt;
                      &lt;value type="java.io.File"&gt;classpath:security/MyEntityId_sp.xml&lt;/value&gt;
                  &lt;/constructor-arg&gt;
                  &lt;property name="parserPool" ref="parserPool"/&gt;
              &lt;/bean&gt;
          &lt;/constructor-arg&gt;
          &lt;constructor-arg&gt;
              &lt;bean class="org.springframework.security.saml.metadata.ExtendedMetadata"&gt;
                 &lt;property name="local" value="true"/&gt;
                 &lt;property name="alias" value="myAlias"/&gt;
                 &lt;property name="securityProfile" value="metaiop"/&gt;
                 &lt;property name="sslSecurityProfile" value="pkix"/&gt;
                 &lt;property name="signingKey" value="apollo"/&gt;
                 &lt;property name="encryptionKey" value="apollo"/&gt;
                 &lt;property name="requireArtifactResolveSigned" value="false"/&gt;
                 &lt;property name="requireLogoutRequestSigned" value="false"/&gt;
                 &lt;property name="requireLogoutResponseSigned" value="false"/&gt;
                 &lt;property name="idpDiscoveryEnabled" value="false"/&gt;
              &lt;/bean&gt;
          &lt;/constructor-arg&gt;
      &lt;/bean&gt;
  
      &lt;bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider"&gt;
          &lt;constructor-arg&gt;
              &lt;value type="java.io.File"&gt;classpath:security/IDP-MetaData.xml&lt;/value&gt;
          &lt;/constructor-arg&gt;
          &lt;property name="parserPool" ref="parserPool"/&gt;
      &lt;/bean&gt;
  </code></pre>
  
  <p>Using the Firefox SAML tracer, I can see that the interactions work fine, and the IDP redirect back to my app (the SP) after authenticating the user, with a  valid SAML XML packet. This is not surprising since this IDP is already successfully being used by other SPs. 
  However, it is redirecting to "<a href="http://localhost:8080/saml-demo/saml/SSO/alias/myAlias" rel="nofollow">http://localhost:8080/saml-demo/saml/SSO/alias/myAlias</a>" which in turn throws the following error to the browser...</p>
  
  <blockquote>
  <pre><code> Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Error determining metadata contracts
  </code></pre>
  </blockquote>
  
  <p>Digging into the code a bit further with the Java debugger, I found the real error is deeper in the code. It is thrown by org.springframework.security.saml.metadata.MetadataManager on line 913 when it sees the same alias for both the SP and the IDP. The real error is:</p>
  
  <blockquote>
  <pre><code> MetadataProviderException: Alias myAlias is used both for entity MyEntityId and MyEntityId
  </code></pre>
  </blockquote>
  
  <p>This only other change beyond what the quick start guide has is to the metadataGeneratorFilter: </p>
  
  <pre><code>&lt;bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter"&gt;
      &lt;constructor-arg&gt;
          &lt;bean class="org.springframework.security.saml.metadata.MetadataGenerator"&gt;
              &lt;property name="entityId" value="MyEntityId"/&gt;
              &lt;property name="signMetadata" value="false"/&gt;
          &lt;/bean&gt;
      &lt;/constructor-arg&gt;
  &lt;/bean&gt; 
  </code></pre>
  
  <p>The IDP metadata file contains ...</p>
  
  <pre><code>&lt;md:EntityDescriptor entityID="MyEntityId" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"&gt;
    &lt;md:IDPSSODescriptor WantAuthnRequestsSigned="0" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"&gt;
      &lt;md:KeyDescriptor use="signing"&gt;
        &lt;ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
          &lt;ds:X509Data&gt;
            &lt;ds:X509Certificate&gt;xxxxxx&lt;/ds:X509Certificate&gt;
          &lt;/ds:X509Data&gt;
        &lt;/ds:KeyInfo&gt;
      &lt;/md:KeyDescriptor&gt;
      &lt;md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://auth.myidp.com/sa1234/" index="0" isDefault="1" /&gt;
      &lt;md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://auth.myidp.com/sa1234/" /&gt;
      &lt;md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://auth.myidp.com/sa1234/" /&gt;
    &lt;/md:IDPSSODescriptor&gt;
    &lt;md:AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"&gt;
      &lt;md:KeyDescriptor use="signing"&gt;
        &lt;ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
          &lt;ds:X509Data&gt;
            &lt;ds:X509Certificate&gt;xxxxxx&lt;/ds:X509Certificate&gt;
          &lt;/ds:X509Data&gt;
        &lt;/ds:KeyInfo&gt;
      &lt;/md:KeyDescriptor&gt;
      &lt;md:AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://auth.myidp.com/sa1234/" /&gt;
    &lt;/md:AttributeAuthorityDescriptor&gt;
  &lt;/md:EntityDescriptor&gt;
  </code></pre>
  
  <p>Here is the contents of MyEntityId_sp.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
      ID="MyEntityId" entityID="MyEntityId"&gt;
      &lt;md:SPSSODescriptor AuthnRequestsSigned="true"
          WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"&gt;
          &lt;md:KeyDescriptor use="signing"&gt;
              &lt;ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
                  &lt;ds:X509Data&gt;
                      &lt;ds:X509Certificate&gt;xxx&lt;/ds:X509Certificate&gt;
                  &lt;/ds:X509Data&gt;
              &lt;/ds:KeyInfo&gt;
          &lt;/md:KeyDescriptor&gt;
          &lt;md:KeyDescriptor use="encryption"&gt;
              &lt;ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
                  &lt;ds:X509Data&gt;
                      &lt;ds:X509Certificate&gt;xxx&lt;/ds:X509Certificate&gt;
                  &lt;/ds:X509Data&gt;
              &lt;/ds:KeyInfo&gt;
          &lt;/md:KeyDescriptor&gt;
          &lt;md:SingleLogoutService
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
              Location="http://localhost:8080/saml-demo/saml/SingleLogout/alias/myAlias" /&gt;
          &lt;md:SingleLogoutService
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
              Location="http://localhost:8080/saml-demo/saml/SingleLogout/alias/myAlias" /&gt;
          &lt;md:NameIDFormat&gt;urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
          &lt;/md:NameIDFormat&gt;
          &lt;md:NameIDFormat&gt;urn:oasis:names:tc:SAML:2.0:nameid-format:transient
          &lt;/md:NameIDFormat&gt;
          &lt;md:NameIDFormat&gt;urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
          &lt;/md:NameIDFormat&gt;
          &lt;md:NameIDFormat&gt;urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
          &lt;/md:NameIDFormat&gt;
          &lt;md:NameIDFormat&gt;urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
          &lt;/md:NameIDFormat&gt;
          &lt;md:AssertionConsumerService
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
              Location="http://localhost:8080/saml-demo/saml/SSO/alias/myAlias"
              index="0" isDefault="true" /&gt;
          &lt;md:AssertionConsumerService
              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/saml-demo/saml/SSO/alias/myAlias"
              index="1" /&gt;
      &lt;/md:SPSSODescriptor&gt;
  &lt;/md:EntityDescriptor&gt;
  </code></pre>