spring-projects / spring-security

Spring Security
http://spring.io/projects/spring-security
Apache License 2.0
8.72k stars 5.86k forks source link

Allow Saml2MetadataFilter to work without AssertingPartyDetails in RelyingPartyRegistration #11369

Open emopti-jrufer opened 2 years ago

emopti-jrufer commented 2 years ago

Expected Behavior

Saml2MetadataFilter should not require information about an identity provider / asserting party in order to generate the metadata. The RelyingPartyRegistration is intended to be a representation of both the relying part and the asserting party. Since the metadata is a representation solely of the relying party not sure if the RelyingPartyRegistration should be used or potentially modified to allow creating the RelyingPartyRegistration without AssertingPartyDetails.

Current Behavior

Current behavior utilizes RelyingPartyRegistration which requires AssertingPartyDetails to be configured.

Context We are having to add fake data to the asserting party details that is part of RelyingPartyRegistration in order to generate metadata.

jzheaux commented 2 years ago

@emopti-jrufer, thanks for the suggestion. This may take some time to sort out as there is no domain object in Spring Security that contains only the relying party information. I'm placing this in the backlog for the time being.

In the meantime, can you clarify why you are filling out fake data for the asserting party? I'm guessing that your application does coordinate with an asserting party, so I wonder what your arrangement is such that you cannot use the RelyingPartyRegistration tied to that relying party/asserting party pair.

emopti-jrufer commented 2 years ago

@jzheaux We have a multi tenant SaaS application where we provide our customers access to download the Service Provider SAML Metadata before it is configured in the application. Basically we are requesting the IDP metadata from our customers at the same time we share our SP metadata. We prefer not requiring the IDP information before allowing access to the SP metadata. This is something that are currently using with the legacy SAML extension. For our use case the metadata our application generates is determined by the hostname where the entityId is unique to that hostname. We allow multiple IDPs to be configured per hostname but do not change the metadata based on the IDP. For our workaround we are generating the RelyingPartyRegistration dynamically with a custom RelyingPartyRegistrationResolver instead of looking up in a repository.

One possible option is to expand the purpose of RelyingPartyRegistration to be either SP and IDP or just SP. An additional build method with a corresponding constructor could be added that is specifically for SP only. Ex: buildForMetadata. This would allow implementors to declaratively know they are creating a registration solely generating metadata.

    private RelyingPartyRegistration(String registrationId, String entityId, String assertionConsumerServiceLocation,
            Saml2MessageBinding assertionConsumerServiceBinding, String singleLogoutServiceLocation,
            String singleLogoutServiceResponseLocation, Collection<Saml2MessageBinding> singleLogoutServiceBindings, String nameIdFormat,
            Collection<Saml2X509Credential> decryptionX509Credentials,
            Collection<Saml2X509Credential> signingX509Credentials) {
...
}

public RelyingPartyRegistration buildForMetadata() {
...
)
peterhaochen47 commented 5 months ago

Plus one on this.

We are implementing a use case where the SAML SP metadata needs to be downloadable before the asserting party is set up. I think this is because some SAML IDPs want you to supply the SAML SP metadata first in order to set up the asserting party config.

For context, we are maintaining an identity proxy app where customers can integrate our app with whatever SAML IDPs of their choice, in runtime. So in our app code, we need to stay agnostic to what the exact SAML IDPs / asserting parties are, and make that configurable via API in runtime.

jzheaux commented 2 months ago

I think one thing that we could at least do is provide an interface, say RelyingPartyMetadata, that RelyingPartyRegistration implements. With the introduction of Saml2MetadataResponseResolver, I think we could introduce an interface that takes an Iterable<RelyingPartyMetadata> or similar and works out a metadata listing from there. There may be a way to also introduce an implementation of RelyingPartyMetadata that doesn't require an asserting party details instance.