Sustainsys / Saml2

Saml2 Authentication services for ASP.NET
Other
959 stars 602 forks source link

Multiple separate SAML-IdPs in IdSrv3 #325

Closed iSOcH closed 8 years ago

iSOcH commented 8 years ago

This issue (question) is related to #304 and #308.

(How) is it possible to add multiple SAML-IdPs in Identityserver3 using Kentor.AuthServices? As I want to show those IdPs as distinct login-possibilities on the loginsite of IdSrv3 I created multiple KentorAuthServicesAuthenticationOptions and used those (each with a separate IdentityProvider-Entry):

var kentorIdpStub = new KentorAuthServicesAuthenticationOptions(false) {
    SPOptions = new SPOptions {
        EntityId = new System.IdentityModel.Metadata.EntityId("http://some.id.for.IdStub")
    },
    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "kentorStub",
    Caption = "SAML zu Kentor stubIdp"
};
kentorIdpStub.IdentityProviders.Add(new Kentor.AuthServices.IdentityProvider(new System.IdentityModel.Metadata.EntityId("http://stubidp.kentor.se/Metadata"), kentorIdpStub.SPOptions) {
    LoadMetadata = true
});
app.UseKentorAuthServicesAuthentication(kentorIdpStub);

var kentorOkta = new KentorAuthServicesAuthenticationOptions(false) {
    SPOptions = new SPOptions {
        EntityId = new System.IdentityModel.Metadata.EntityId("http://some.id.for.okta"),
    },
    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "okta",
    Caption = "SAML zu Okta"
};
kentorOkta.IdentityProviders.Add(new Kentor.AuthServices.IdentityProvider(new System.IdentityModel.Metadata.EntityId("http://www.okta.com/exk5ckcocgvWyCovt0h7"), kentorOkta.SPOptions) {
    LoadMetadata = true,
    MetadataUrl = new System.Uri("https://dev-199246.oktapreview.com/app/exk5ckcocgvWyCovt0h7/sso/saml/metadata")
});
app.UseKentorAuthServicesAuthentication(kentorOkta);

This way, however, only the first IdP works. The second one fails with the following exception when the response of the IdP is POSTed back to IdSrv (to: https://localhost:44333/core/AuthServices/Acs) [KeyNotFoundException: No Idp with entity id "http://www.okta.com/exk5ckcocgvWyCovt0h7" found.], probably because it looks in IdentityProviders-Dictionary of the first AuthService.

Is there an option similiar to CallbackPath on WsFederationAuthenticationOptions (see last paragraph on https://identityserver.github.io/Documentation/docsv2/configuration/identityProviders.html)? Or do I have to change something else in the configuration to separate multiple SAML-IdPs in IdSrv3?

AndersAbel commented 8 years ago

AuthServices is designed to be able to work with multiple instances, but they must be assigned unique URLs in that case. Set the ModulePath of one of the configs to something else than AuthServices.

What's happening now is that the first instance (the stub idp one) will receive the response from the okta and reply wih "unknown idp".

Another option for multiple idps is to use one instance of AuthServices and use a discovery service to let the user chose idp in an intermediate step. To get that working with IdSrv3 #182 needs to be fixed first.

iSOcH commented 8 years ago

Woah, insane response time. And works like a charm, thanks a lot!

Maybe this helps someone else, here is the edited code from above:

var kentorIdpStub = new KentorAuthServicesAuthenticationOptions(false) {
    SPOptions = new SPOptions {
        EntityId = new System.IdentityModel.Metadata.EntityId("http://some.id.for.IdStub")
        ModulePath = "/SAML/kentorStub"
    },
    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "kentorStub",
    Caption = "SAML zu Kentor stubIdp",
};
kentorIdpStub.IdentityProviders.Add(new Kentor.AuthServices.IdentityProvider(new System.IdentityModel.Metadata.EntityId("http://stubidp.kentor.se/Metadata"), kentorIdpStub.SPOptions) {
    LoadMetadata = true
});
app.UseKentorAuthServicesAuthentication(kentorIdpStub);

var kentorOkta = new KentorAuthServicesAuthenticationOptions(false) {
    SPOptions = new SPOptions {
        EntityId = new System.IdentityModel.Metadata.EntityId("http://some.id.for.okta"),
        ModulePath = "/SAML/okta"
    },
    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "okta",
    Caption = "SAML zu Okta"
};
kentorOkta.IdentityProviders.Add(new Kentor.AuthServices.IdentityProvider(new System.IdentityModel.Metadata.EntityId("http://www.okta.com/exk5ckcocgvWyCovt0h7"), kentorOkta.SPOptions) {
    LoadMetadata = true,
    MetadataUrl = new System.Uri("https://dev-199246.oktapreview.com/app/exk5ckcocgvWyCovt0h7/sso/saml/metadata")
});
app.UseKentorAuthServicesAuthentication(kentorOkta);