IdentityServer allows your ASP.NET Core website to act as an OpenID Provider and OAuth authorization server, providing single sign-on (SSO) across your applications.
But what if you want to allow SAML applications to use your SSO solution or to federate with an external SAML identity provider? Do you need to spin up a custom gateway to bridge protocols? Can you support them within your existing IdentityServer installation?
This is where our Rock Solid Knowledge SAML2P component comes in.
In this tutorial, you’ll learn how to use our SAML2P component with Duende IdentityServer or IdentityServer4 to build a cross-protocol SSO solution. By the end of this tutorial, you will be able to allow SAML applications to log in using your IdentityServer and federate with external SAML identity providers for logins.
The Security Assertion Markup Language (SAML) protocol is used to exchange authentication data between parties. There are two sides to the SAML protocol: Identity Provider (IdP) and Service Provider (SP).
We provide both SAML SP and SAML IdP implementations for Duende IdentityServer and IdentityServer4. You can enable your IdentityServer to act as SAML IdP, SAML SP, or both.
SAML Identity Provider
As a SAML Identity Provider, you can support cross-protocol SSO by allowing some applications to authenticate with your IdentityServer using SAML and others using OpenID Connect. In this role, IdentityServer acts in its traditional role as an authorization server/identity provider. Both protocols share the same SSO session, providing the user with a single sign-on experience.
All the SAML interactions are abstracted away in the IdentityServer, allowing for seamless cross-protocol SSO.
SAML Service Provider
As a service provider, you can federate with external SAML identity providers. The external identity provider holds the user credentials, and you send them SAML authentication requests.
In this role, IdentityServer uses an external identity provider for logins, similar to how you would offer “login using Google” functionality.
2. Getting Started
Project Setup
This article will build upon the basic in-memory IdentityServer template, which adds a basic UI, test users, and in-memory clients and resources. You can install this template using the IdentityServer .NET CLI command dotnet new isinmem.
You can find the completed source code for this article on GitHub.
License
Our SAML component requires a valid license. You can get a demo license by signing up on our products page or reaching out to us at [email protected].
Install RSK SAML2P library
You will need to install our IdentityServer-specific SAML library.
Duende IdentityServer SAML library:
dotnet add package Rsk.Saml.DuendeIdentityServer
IdentityServer4 SAML library:
dotnet add package Rsk.Saml.IdentityServer4
3. IdentityServer as a SAML Identity Provider
To enable SAML applications to authenticate using your IdentityServer, you must register our plugin by updating the call to AddIdentityServer with the following:
The AddSamlPlugin adds the necessary SAML dependencies to receive SAML requests and send SAML responses. You need to provide the licencee and license key that you acquired in the Getting Started section.
Next, there is a call to .AddInMemoryServiceProviders, which registers a collection of service providers that can authenticate with your IdentityServer. This will be populated once you add a service provider later.
Our SAML Identity Provider uses the IdentityServer key store to extract the configured keys. You require X509 certificates and RS256 keys. This means that you won’t be able to use the AddDeveloperSigningCredential registration from IdentityServer. Instead, you will need to use AddSigningCredential or the Automatic Key Management feature. If you are still developing, you can find a private key for development in the completed source code for this repository. Otherwise, you can use makecert, OpenSSL, or PowerShell to generate a new key.
And finally, we need to add SAML to the middleware by chaining the call to UseIdentityServer.
And that’s all that’s needed to add SAML support in your IdentityServer!
SAML Identity Provider Metadata
You can now retrieve your SAML Identity Provider metadata document by visiting the path /saml/metadata.
Your metadata document contains all the information that service providers need to integrate with you, such as your EntityId, Single Sign-On (SSO) endpoints, supported signing methods, and public signing key. Check out an Example IdP Metadata in our product documentation.
Add a SAML Service Provider
Now that IdentityServer has been configured to handle SAML, you can define a service provider that can authenticate using your IdentityServer. To do this, you need to create the usual Client entry within IdentityServer and configure the SAML specifics using the ServiceProvider object.
The Client entry needs to be added to the IdentityServer client store, for example, in your call to AddInMemoryClients.
The ServiceProvider entry needs to be added to your service provider store, for example, in your call to AddInMemoryServiceProviders.
new Rsk.Saml.Models.ServiceProvider
{
EntityId = "https://localhost:5001/saml",
SigningCertificates = {new X509Certificate2("/*The SP’s public signing key*/")},
AssertionConsumerServices = { new Service(SamlConstants.BindingTypes.HttpPost, "https://localhost:5001/signin-saml") }
}
NOTE: The ClientId and EntityId must be identical.
The ServiceProvider entry contains all the information you need to integrate with the partner service provider, including their unique Entity ID, Assertion Consumer Services (ACS endpoints), and public signing key. You can obtain all this information from the service provider’s metadata document.
The public signing key is only necessary if you want the incoming SAML requests to be signed.
The AssertionConsumerService is made up of the endpoint URL and the binding type to use for sending SAML responses. We currently support HTTP Redirect, HTTP POST, and HTTP Artifact bindings.
To implement a persistent store for ServiceProvider configuration, please check out our Data Storage and Persistence documentation.
4. IdentityServer as a SAML Service Provider
Now for the other side of the story. You will update IdentityServer to act as a SAML Service Provider. The users will be able to log into IdentityServer using an account handled by an external SAML Identity Provider.
Our SAML SP side of the component acts much in the same way as other ASP.NET Core authentication libraries for external providers (e.g., OpenID Connect), where you have a local authentication type (a cookie) and then an external authentication provider (SAML2P).
Our SP implementation can be integrated into any ASP.NET Core application, such as IdentityServer.
To add SAML authentication to your IdentityServer, you will need to add the following code in your startup configuration:
services.AddAuthentication()
.AddSaml2p("saml2p", options => {
options.Licensee = “DEMO";
options.LicenseKey = "/*your DEMO licenseKey*/";
// Details about the identity provider you are integrating with
options.IdentityProviderOptions = new IdpOptions
{
EntityId = "https://localhost:5000",
SingleSignOnEndpoint = new SamlEndpoint("https://localhost:5000/saml/sso", SamlBindingTypes.HttpRedirect),
SigningCertificates = { new X509Certificate2("/*The IdP’s public signing key*/") }
};
// Details about yourself
options.ServiceProviderOptions = new SpOptions
{
// your unique identifier
EntityId = "https://localhost:5001/saml",
// this will be your SP metadata endpoint
MetadataPath = "/samlsp-metadata",
// optional
SignAuthenticationRequests = false
};
// this will be your ACS endpoint
options.CallbackPath = "/signin-saml";
// this is the cookie that the external SAML identity will be saved to
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
});
Configuring SAML2P Authentication Handler
License
You need to provide the licencee and license key you acquired in the Getting Started section.
Define yourself (SP)
The ServiceProviderOptions configures information about yourself, such as your unique EntityId.
If the identity provider requires you to sign SAML requests, you will need to provide a private signing key using SigningCertificate and set SignAuthenticationRequests to true.
We recommend signing SAML requests whenever possible. Digital signatures provide means for verifying the validity and authenticity of the requests. There are no other viable mechanisms available for cryptographically binding requests to a specific SP.
Information about the partner IdP
You must provide information about the identity provider you are integrating with using IdentityProviderOptions. The IdP’s metadata document contains all the information you need to specify.
The identity provider’s signing certificate is the public key that will be used to verify the incoming SAML responses. You can load the public signing key from a file or by converting the base64 encoded value found in the identity provider’s metadata:
new X509Certificate2(Convert.FromBase64String(@"MIIFTjCCBDagAwIBAg...);
We also support Automatic Metadata Lookup, which avoids you having to retrieve and parse the metadata document manually.
Define ACS Endpoint
The CallbackPath is your Assertion Consumer Service (ACS) endpoint. The IdP will send SAML responses/assertions to this endpoint. If you haven’t set this path, the default value is /saml/acs.
Our SAML authentication handler implements this endpoint, so you don’t need to write any additional code to listen on this endpoint.
You can now retrieve your metadata document by visiting the path you configured as ServiceProviderOptions.MetadataPath. If you haven’t set this path, the default value is /saml.
Your metadata contains all the information that the identity provider needs to integrate with you, such as your EntityId, ACS endpoints, and public signing key. Check out an Example SP Metadata in our product documentation.
Handling the External Identity
Note that you are using the IdentityServer’s temporary cookie handler, IdentityServerConstants.ExternalCookieAuthenticationScheme, as the SignInScheme.
We recommend following the IdentityServer guide for integrating with an external IdP. A temporary cookie is used to remember the external identity. Then a callback method is used to perform custom business logic to map claims and link the external user to a local user.
The completed source code, including test keys, can be found on GitHub.
6. Next Steps
This tutorial covered the basics of enabling your Duende IdentityServer or IdentityServer4 to act as a SAML Identity Provider or a SAML Service Provider. This should get you started, but don’t forget to use a persistent ServiceProvider store instead of the in-memory store before going into production.
For more advanced use cases, check out our other articles, QuickStarts, and feature-specific documentation. Here are a few topics that you might find helpful:
SAML works really well for server-side applications, providing single sign-on across your applications. But can you use SAML with modern application types such as SPAs and mobile apps?
SAML single sign-on (SSO) allows the end-user to securely authenticate across multiple applications by logging in once using one set of credentials. However, authentication is only the first half of the story.