It is a common use-case to allow users to login using external Identity Providers, such as Azure AD or Google.
ASP.NET Core allows you to add multiple authentication handlers, enabling you to federate with multiple external Identity Providers.
Adding multiple SAML Identity Providers
In ASP.NET Core, you can add multiple authentication handlers in a chain.
Here's an example showing how to setup federation with two SAML external Identity Providers:
services.AddAuthentication()
.AddCookie("cookie")
.AddSaml2p("idp1", options => {
options.Licensee = "";
options.LicenseKey = "";
options.IdentityProviderOptions = new IdpOptions
{
EntityId = "https://idp-1"
// Other configuration code removed for brevity
};
options.ServiceProviderOptions = new SpOptions
{
EntityId = "https://mySP",
MetadataPath = "/saml/metadata-saml-1"
};
options.CallbackPath = "/signin-saml-1";
options.SignedOutCallbackPath = "/signout-saml-1";
options.SignInScheme = "cookie";
})
.AddSaml2p("idp2", options => {
options.Licensee = "";
options.LicenseKey = "";
options.IdentityProviderOptions = new IdpOptions
{
EntityId = "https://idp-2",
// Other configuration code removed for brevity
};
options.ServiceProviderOptions = new SpOptions
{
EntityId = "https://mySP",
MetadataPath = "/saml/metadata-saml-2"
};
options.CallbackPath = "/signin-saml-2";
options.SignedOutCallbackPath = "/signout-saml-2";
options.SignInScheme = "cookie";
});
The key configuration to notice in this example is that the callback
, signedOutCallbackPath
and MetadataPath
are all unique per Service Provider configuration.
We have architected our component in the same way as Microsoft's OpenID Connect authentication handler, which uses a specific redirect URI per Identity Provider (IdP).
This means that our SAML component uses different Assertion Consumer Service (CallbackPath
), Single Logout (SignedOutCallbackPath
) and Metadata (MetadataPath
) endpoints per configured Identity Provider.
This approach allows you to sidestep a whole range of attacks, including IdP-mixup attacks.
When using multiple authentication handlers, ASP.NET Core chooses the first handler with a matching route.
If the paths are not unique, you could end up in a situation where the challenge is issued by one scheme but validated by the other which will cause validation errors. For example, the response validation may fail with an error such as "Invalid SAML response issuer".
However, if you need to use a single metadata endpoint and ACS endpoint, you could set the SkipUnrecognizedRequests
option to true.
This prevents authentication failures upon SAML response validation failure.
But we highly discourage this approach as it exposes you to unnecessary risks.
Dynamically Load Authentication Schemes
The ASP.NET Core AddAuthentication
method allows you to add Identity Providers to the DI container on application startup.
This means that you will need to re-compile and restart your application every time you want to make any changes to your configuration.
Two products are available that we recommend to allow you to load authentication configuration during run-time. You can add, configure or remove providers at runtime without the need for any code changes, deployments, or application restarts.
Duende Dynamic Providers
The Dynamic Providers feature of Duende IdentityServer allows you to load providers at runtime, although this require a Duende business license.
Our SAML component contains support for Duende Dynamic Providers, which means you can dynamically load SAML Service Provider configuration using Duende during run-time. You can learn more about this feature at SAML support for Dynamic Providers.
Duende Dynamic Provider requires an Enterprise License
RSK Dynamic Authentication Providers
Our Rock Solid Knowledge Dynamic Authentication Providers component allows an ASP.NET Core application to load authentication configuration during run-time. It works with Duende IdentityServer, allowing you to build multi-tenancy federated IdentityServer solutions. It supports OIDC, SAML, and WS-Federation providers out-of-the-box.