To expose the SAML metadata endpoint we have to register a Filter:

DefaultRelyingPartyRegistrationResolver relyingPartyRegistrationResolver =
        new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(
        relyingPartyRegistrationResolver,
        new OpenSamlMetadataResolver());

http
    // ...
    .saml2Login(withDefaults())
    .addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class);

The default URL for that filter is /saml2/service-provider-metadata/{registrationId}. If there is a need to change that URL for something like /saml/metadata, a RelyingPartyRegistrationResolver should be customized to resolve the RelyingPartyRegistration without relying on the registrationId template variable.

RelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver((id) -> relyingPartyRegistrationRepository.findByRegistrationId("one"));
Saml2MetadataFilter metadataFilter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());

Given that customizing the RelyingPartyRegistrationResolver is less common, a new constructor that accepts a RelyingPartyRegistrationRepository could be added to Saml2MetadataFilter, simplifying the way we construct it:

public final class Saml2MetadataFilter extends OncePerRequestFilter {

        // ...

    public Saml2MetadataFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository, Saml2MetadataResolver saml2MetadataResolver) {
        this(new DefaultRelyingPartyRegistrationResolver(relyingPartyRegistrationRepository), saml2MetadataResolver);
    }

        // ...
}

and then

Saml2MetadataFilter metadataFilter = new Saml2MetadataFilter(this.relyingPartyRegistrationRepository, new OpenSamlMetadataResolver());

Comment From: jzheaux

@marcusdacoregio, thanks for this write-up.

We want to avoid direct references to OpenSaml in classes not named OpenSamlXXX. Given that, I think the constructor will still require two parameters.

Comment From: marcusdacoregio

Thanks, @jzheaux. The description is now updated.

Comment From: cotnic

Hello @marcusdacoregio can I help with this issue?

Comment From: marcusdacoregio

Hello @cotnic, of course, it’s now yours. Let us know if you have any difficulties.

Comment From: cotnic

@marcusdacoregio I want to start on this issue. I would like to know from which branch onward is this fix going to be included.

Comment From: marcusdacoregio

Hi @cotnic, you can use the main branch since this is a new feature.