I have the following use case I'm trying to implement:
We have a Service Provider, and we want our clients to be able to use it using their Identity Provider. This means we'll need to have more than one Identity Provider. I have an implementation that works, but I'm not sure if the approach is what you'd have in mind to solve the problem, which is why I haven't done a pull request for it. The full code is in the multi-idp
branch of my fork, but the basics work like this:
First, I made the SAMLConfigurer's identityProvider a list. Then I made the SAMLConfigurer's identityProvider()
method create a new instance of IdentityProvider and add it to that list.
Next, I made some modifications to how the metadata gets created so it works with multiple IDPs.
Finally, I added the following method to SAMLConfigurer
to delegate some of the configuration to the class doing the security configuration:
public SAMLConfigurer delegateConfig(Function<SAMLConfigurer, SAMLConfigurer> delegate) {
return delegate.apply(this);
}
It looks a little weird, but I couldn't create an IdentityProvider
outside the SAMLConfigurer
, and the delegate lets me use the dsl in helper methods like the one I use to iterate over our supported IDPS, doing the following for each one:
samlConfigurer
.identityProvider()
.metadataFilePath("file://" + f.getAbsolutePath())
.metadataTrustCheckEnabled(false);
I can then do this in my WebSecurityConfigurerAdapter implementation:
.http(saml())
.apply(saml())
.serviceProvider()
.keyStore()
.storeFilePath(samlProperties.getKeystore())
.password(samlProperties.getKeystorePassword())
.keyname(samlProperties.getDefaultKey())
.keyPassword(samlProperties.getDefaultKeyPassword())
.and()
.protocol("http")
.hostname("localhost:8080")
.basePath("/")
.and()
.delegateConfig(this::idpHelper)
What do you think?