ComponentSpace SAML v2.0 IdentityServer4 Integration Guide Copyright ComponentSpace Pty Ltd 2017-2018. All rights reserved. www.componentspace.com
Contents Introduction... 1 IdentityServer4 as the Service Provider... 1 Adding SAML Support... 1 Service Provider Configuration... 2 Application Startup... 2 Identity Provider Configuration... 3 SP-Initiated SSO... 3 IdP-Initiated SSO... 8 SAML Logout... 8 IdentityServer4 as the Identity Provider... 11 Adding SAML Support... 11 Identity Provider Configuration... 12 Middleware vs API... 13 SAML API... 13 Application Startup... 13 SAML Controller... 13 SAML Middleware... 15 Application Startup... 15 Service Provider Configuration... 16 SP-Initiated SSO... 17 IdP-Initiated SSO... 19 SAML Logout... 19 i
Introduction IdentityServer4 doesn t natively support SAML SSO but it is extensible. This document describes how to add SAML support to IdentityServer4 acting as either an identity provider or service provider. The reader is assumed to have an existing IdentityServer4 project. For information on building, configuring and running IdentityServer4, refer to the following documentation. https://identityserver4.readthedocs.io/en/release/index.html IdentityServer4 as the Service Provider IdentityServer4 supports users signing in using external identity providers. IdentityServer4 is the SAML service provider and the external providers are the SAML identity providers. The application authenticating to IdentityServer4 may use any available protocol (e.g. OpenID Connect). The following sections described how to enable sign-on using external SAML identity providers. Adding SAML Support Add the ComponentSpace.Saml2 NuGet package to the IdentityServer4 project. Add the Certificates folder to the IdentityServer4 project. The following certificate files may be copied from the ExampleServiceProvider project. sp.pfx 1
idp.cer Service Provider Configuration In IdentityServer4 s appsettings.json, include the SAML configuration. "SAML": "$schema": "https://www.componentspace.com/schemas/saml-config-schema-v1.0.json", "Configurations": [ "LocalServiceProviderConfiguration": "Name": "https://identityserver4", "Description": "IdentityServer4", "AssertionConsumerServiceUrl": "http://localhost:5000/saml/assertionconsumerservice", "SingleLogoutServiceUrl": "http://localhost:5000/saml/singlelogoutservice", "LocalCertificates": [ "FileName": "certificates/sp.pfx", "Password": "password" ], "PartnerIdentityProviderConfigurations": [ "Name": "https://exampleidentityprovider", "Description": "Example Identity Provider", "SignAuthnRequest": true, "SingleSignOnServiceUrl": "https://localhost:44313/saml/singlesignonservice", "SingleLogoutServiceUrl": "https://localhost:44313/saml/singlelogoutservice", "PartnerCertificates": [ "FileName": "certificates/idp.cer" ] ] ], "PartnerName": "https://exampleidentityprovider" For information on SAML configuration, refer to the SAML v2.0 Configuration Guide. Application Startup In the ConfigureServices method in IdentityServer4 s Startup class, add the following. // Add SAML SSO services. services.addsaml(configuration.getsection("saml"); // Add the SAML authentication handler. services.addauthentication().addsaml(options => 2
options.signinscheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.partnername = () => Configuration["PartnerName"]; ); For more information, refer to the SAML v2.0 Developer Guide. Identity Provider Configuration The following partner service provider configuration is included in the example identity provider s SAML configuration. "Name": "https://identityserver4", "Description": "IdentityServer4", "WantAuthnRequestSigned": true, "SignSamlResponse": true, "AssertionConsumerServiceUrl": "http://localhost:5000/saml/assertionconsumerservice", "SingleLogoutServiceUrl": "http://localhost:5000/saml/singlelogoutservice", "PartnerCertificates": [ "FileName": "certificates/sp.cer" ] SP-Initiated SSO The reader is assumed to have an application that authenticates to IdentityServer4 using OpenID Connect or some other protocol. For more information, refer to the IdentityServer4 documentation. Browse to the application and initiate login. 3
At the IdentityServer4 login page, click the SAML external login button. 4
Login at the identity provider. 5
Allow the requested permissions. 6
The user is automatically logged in at the service provider. 7
IdP-Initiated SSO IdP-initiated SSO is not supported by IdentityServer4. SAML Logout IdP-initiated SAML logout is not supported by IdentityServer4. SP-initiated SAML logout is supported. Initiate logout at the application. 8
You are logged out at IdentityServer4. 9
Click the link to return to the application. 10
IdentityServer4 as the Identity Provider IdentityServer4 supports adding authentication protocols. The following sections described how to enable SAML SSO to IdentityServer4. Authenticating applications act as SAML service providers and IdentityServer4 is the SAML identity provider. Adding SAML Support Add the ComponentSpace.Saml2 NuGet package to the IdentityServer4 project. 11
Add the Certificates folder to the IdentityServer4 project. The following certificate files may be copied from the ExampleIdentityProvider project. idp.pfx sp.cer Identity Provider Configuration In IdentityServer4 s appsettings.json, include the SAML configuration. "SAML": "$schema": "https://www.componentspace.com/schemas/saml-config-schema-v1.0.json", "Configurations": [ "LocalIdentityProviderConfiguration": "Name": "https://identityserver4", "Description": "IdentityServer4", "SingleSignOnServiceUrl": "http://localhost:5000/saml/singlesignonservice", "SingleLogoutServiceUrl": "http://localhost:5000/saml/singlelogoutservice", "ArtifactResolutionServiceUrl": "http://localhost:5000/saml/artifactresolutionservice", "LocalCertificates": [ "FileName": "certificates/idp.pfx", "Password": "password" ], "PartnerServiceProviderConfigurations": [ "Name": "https://exampleserviceprovider", "Description": "Example Service Provider", 12
"WantAuthnRequestSigned": true, "SignSamlResponse": true, "AssertionConsumerServiceUrl": "https://localhost:44360/saml/assertionconsumerservice", "SingleLogoutServiceUrl": "https://localhost:44360/saml/singlelogoutservice", "ArtifactResolutionServiceUrl": "https://localhost:44360/saml/artifactresolutionservice", "PartnerCertificates": [ "FileName": "certificates/sp.cer" ] ] ] For information on SAML configuration, refer to the SAML v2.0 Configuration Guide. Middleware vs API When adding SSO support to IdentityServer4, you have a choice between: Adding the SAML authentication handler or SAML middleware Making explicit SAML API calls within the application Both approaches are described in the following sections. SAML flows are the same for the two approaches. For more information, refer to the SAML v2.0 Developer Guide. SAML API Application Startup In the ConfigureServices method in the application s Startup class, add the following. // Add SAML SSO services. services.addsaml(configuration.getsection("saml"); For more information, refer to the SAML v2.0 Developer Guide. SAML Controller Add a SAML controller to the IdentityServer4 project. This controller includes actions for handling SAML single sign-on and logout. public class SamlController : Controller private readonly ISamlIdentityProvider _samlidentityprovider; private readonly IIdentityServerInteractionService _identityserverinteractionservice; private readonly IMessageStore<LogoutMessage> _logoutmessagestore; public SamlController( ISamlIdentityProvider samlidentityprovider, 13
IIdentityServerInteractionService identityserverinteractionservice, IMessageStore<LogoutMessage> logoutmessagestore) _samlidentityprovider = samlidentityprovider; _identityserverinteractionservice = identityserverinteractionservice; _logoutmessagestore = logoutmessagestore; public async Task<ActionResult> SingleSignOnService() // Receive the authn request from the service provider (SP-initiated SSO). await _samlidentityprovider.receivessoasync(); // If the user is logged in at the identity provider, complete SSO immediately. // Otherwise have the user login before completing SSO. if (User.Identity.IsAuthenticated) await CompleteSsoAsync(); return new EmptyResult(); else return RedirectToAction("SingleSignOnServiceCompletion"); [Authorize] public async Task<ActionResult> SingleSignOnServiceCompletion() await CompleteSsoAsync(); return new EmptyResult(); public async Task<ActionResult> SingleLogoutService() // Receive the single logout request or response. // If a request is received then single logout is being initiated by a partner service provider. // If a response is received then this is in response to single logout having been initiated // by the identity provider. var sloresult = await _samlidentityprovider.receivesloasync(); if (sloresult.isresponse) if (sloresult.hascompleted) // IdP-initiated SLO has completed. return RedirectToPage("/Index"); else // Specify the display name and return URL for logout. var logoutmessage = new Message<LogoutMessage>(new LogoutMessage 14
ClientName = "SAML Service Provider", PostLogoutRedirectUri = "/SAML/SingleLogoutServiceCompletion", DateTime.UtcNow); var logoutid = await _logoutmessagestore.writeasync(logoutmessage); // Logout locally. return RedirectToAction("Logout", "Account", new logoutid = logoutid ); return new EmptyResult(); public async Task<ActionResult> SingleLogoutServiceCompletion() // Respond to the SP-initiated SLO request indicating successful logout. await _samlidentityprovider.sendsloasync(); return new EmptyResult(); private Task CompleteSsoAsync() // Get the name of the logged in user. var username = User.Identity.Name; // Include claims as SAML attributes. var attributes = new List<SamlAttribute>(); foreach (var claim in ((ClaimsIdentity)User.Identity).Claims) attributes.add(new SamlAttribute(claim.Type, claim.value)); // The user is logged in at the identity provider. // Respond to the authn request by sending a SAML response containing a SAML assertion to the SP. return _samlidentityprovider.sendssoasync(username, attributes); SAML Middleware Application Startup In the ConfigureServices method in the application s Startup class, add the following. // Add SAML SSO services. services.addsaml(configuration.getsection("saml"); // Add SAML Middleware services. services.addsamlmiddleware(); In the Configure method in the application s Startup class, add the following. This should be placed after the UseIdentityServer call. 15
// Use SAML middleware. app.usesaml(); // Specify the display name and return URL for logout. app.use(async (context, next) => if (context.request.path.value.equals("/account/logout", StringComparison.OrdinalIgnoreCase) && string.isnullorempty(context.request.query["logoutid"])) var identityserverinteractionservice = context.requestservices.getrequiredservice<iidentityserverinteractionservice>(); var logoutmessagestore = context.requestservices.getrequiredservice<imessagestore<logoutmessage>>(); var logoutmessage = new Message<LogoutMessage>(new LogoutMessage ClientName = "SAML Service Provider", PostLogoutRedirectUri = "/SAML/SingleLogoutServiceCompletion", DateTime.UtcNow); var logoutid = await logoutmessagestore.writeasync(logoutmessage); context.request.querystring = context.request.querystring.add("logoutid", logoutid); await next(); ); For more information, refer to the SAML v2.0 Developer Guide. Service Provider Configuration The following partner identity provider configuration is included in the example service provider s SAML configuration. "Name": "https://identityserver4", "Description": "IdentityServer4", "SignAuthnRequest": true, "SingleSignOnServiceUrl": "http://localhost:5000/saml/singlesignonservice", "SingleLogoutServiceUrl": "http://localhost:5000/saml/singlelogoutservice", "ArtifactResolutionServiceUrl": "http://localhost:5000/saml/artifactresolutionservice", "PartnerCertificates": [ "FileName": "certificates/idp.cer" ] Ensure the PartnerName specifies the correct partner identity provider. "PartnerName": "https://identityserver4" 16
SP-Initiated SSO Browse to the example service provider and click the button to SSO to the identity provider. Log into IdentityServer4. 17
The user is automatically logged in at the service provider. 18
IdP-Initiated SSO IdP-initiated SSO is not supported by IdentityServer4. SAML Logout IdP-initiated SAML logout is not supported by IdentityServer4. SP-initiated SAML logout is supported. Click the logout link at the example service provider. 19
You are prompted to logout at IdentityServer4. 20
Click the Yes button. 21
Click the link to return to the example service provider. 22
23