Search code examples
springspring-securitysaml-2.0spring-saml

How can I add "Organization" declaration into SP's metadata (Spring SAML)?


Is there any way to include the informations about the Organization into the generated SP's metadata with Spring Security? Because by default I can't see it included in the generated metadata XML.

What I'm currently getting

I've tried to create a custom class SAMLMetadataGenerator which extends the framework's class MetadataGenerator, and then tried to Override the buildExtensions method in the following way:

public class SAMLMetadataGenerator extends MetadataGenerator {

   @Override
   protected Extensions buildExtensions(String entityBaseURL, String entityAlias) {
        super.setIncludeDiscoveryExtension(true);
        Extensions extensions = super.buildExtensions(entityBaseURL, entityAlias);
        if (extensions != null)
            extensions.getUnknownXMLObjects().add(generateOrganization());

        return extensions;
   }

   private Organization generateOrganization() {
    OrganizationBuilder organizationBuilder = new OrganizationBuilder();
    Organization organization = organizationBuilder.buildObject();

    OrganizationNameBuilder organizationNameBuilder = new OrganizationNameBuilder();
    OrganizationName organizationName = organizationNameBuilder.buildObject();
    organizationName.setName(new LocalizedString("ACME", "en"));

    OrganizationDisplayNameBuilder displayNameBuilder = new OrganizationDisplayNameBuilder();
    OrganizationDisplayName organizationDisplayName = displayNameBuilder
            .buildObject();
    organizationDisplayName.setName(new LocalizedString("ACME Corporation", "en"));

    OrganizationURLBuilder organizationURLBuilder = new OrganizationURLBuilder();
    OrganizationURL organizationURL = organizationURLBuilder.buildObject();
    organizationURL.setURL(new LocalizedString("http://spid.serviceprovider.it", "it"));

    organization.getOrganizationNames().add(organizationName);
    organization.getDisplayNames().add(organizationDisplayName);
    organization.getURLs().add(organizationURL);
    return organization;
   }
}

This way the produced SP's metadata is then:

<md:EntityDescriptor
    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="com_xegiy84105_spring_sp" entityID="com:xegiy84105:spring:sp">
    <!-- Other things here -->
    <md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <md:Extensions>
            <idpdisco:DiscoveryResponse
                xmlns:idpdisco="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="http://localhost:8091/DM-WEB/saml/login?disco=true" index="0"/>
            <md:Organization>
                <md:OrganizationName xml:lang="en">ACME</md:OrganizationName>
                <md:OrganizationDisplayName xml:lang="en">ACME Corporation</md:OrganizationDisplayName>
                <md:OrganizationURL xml:lang="it">http://spid.serviceprovider.it</md:OrganizationURL>
            </md:Organization>
        </md:Extensions>
        <!-- Other things here -->
    </md:SPSSODescriptor>
</md:EntityDescriptor>

How it should really be

But the "Organization" block should be inserted without being surrounded by <md:Extensions/> and it should be placed as a direct child of the <md:EntityDescriptor/> block similiar to the following snippet:

<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
    entityID="https://spid.serviceprovider.it"
    ID="_0j40cj0848d8e3jncjdjss...">
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        [...]
    </ds:Signature>
    <md:SPSSODescriptor
        protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"
        AuthnRequestsSigned="true"
        WantAssertionsSigned="true">
        [...]
    </md:SPSSODescriptor>
    <md:Organization>
        <OrganizationName xml:lang="it">Service provider</OrganizationName>
        <OrganizationDisplayName xml:lang="it">Nome service provider</OrganizationDisplayName>
        <OrganizationURL xml:lang="it">http://spid.serviceprovider.it</OrganizationURL>
    </md:Organization>
</md:EntityDescriptor>

What is the correct way to achieve this goal? Thanks.


Solution

  • The reason it's in the extensions is this:

    extensions.getUnknownXMLObjects().add(generateOrganization());
    

    according to the docs for MetadataGenerator you can use:

    generateMetadata()
    

    which returns an EntityDescriptor, which you can add the org to:

    setOrganization(generateOrganization());