Integrating with SAML Identity Providers

Integrating with SAML Identity Providers

On this page

Overview

SAML is an XML-based open-standard for transferring identity data between two entities namely an identity provider (IdP) and a service provider (SP).

This tutorial will demonstrate how to use the Curity Identity Server's SAML2 authenticator to integrate with an external SAML Identity provider for federated authentication. The SAML2 authenticator implements the SAML service provider role.

Federated authentication via SAML is required in many use cases such as allowing business partner users to authenticate using the partner's own authentication systems and policies with familiar credentials that the users will not forget.

The Curity Identity Server's SAML2 authenticator enables application developers to code apps in modern and simple way, using OpenID Connect. Yet user logins can use SAML identity providers when required, without the application code needing to know anything about the SAML protocol.

In essence, the apps will use the OpenID Connect flow to talk to the SAML2 authenticator, and delegate the handling of SAML protocol complexities to the authenticator.

Prerequisites

SAML2 authenticator is available out of the box from version 7.6 onwards, so please ensure that you use the Curity Identity Server in version 7.6 or higher and that you use the SAML2 authenticator.

Download SAML IdP metadata

This tutorial uses samltestid as the SAML IdP. It's a free online SAML2.0 IdP testing service.

To configure the SAML2 authenticator with samltestid SAML IdP, some information namely the entityId, HTTP-Redirect location, IdP url etc., needs to be gathered.

Typically this information is available in the SAML IdP metadata document, samltestid's metadata document is available for download at https://samltest.id/saml/idp. Take a look at the available information in the SAML IdP metadata document.

xml
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="SAMLtestIdP"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0"
xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui"
validUntil="2100-01-01T00:00:42Z" entityID="https://samltest.id/saml/idp">
<IDPSSODescriptor
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
<Extensions>
<shibmd:Scope regexp="false">samltest.id</shibmd:Scope>
<mdui:UIInfo>
<mdui:DisplayName xml:lang="en">SAMLtest IdP</mdui:DisplayName>
<mdui:Description xml:lang="en">A free and basic IdP for testing SAML deployments</mdui:Description>
<mdui:Logo height="90" width="225">https://samltest.id/saml/logo.png</mdui:Logo>
</mdui:UIInfo>
</Extensions>
<KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIDEjCCAfqgAwIBAgIVAMECQ1tjghafm5OxWDh9hwZfxthWMA0GCSqGSIb3DQEB
CwUAMBYxFDASBgNVBAMMC3NhbWx0ZXN0LmlkMB4XDTE4MDgyNDIxMTQwOVoXDTM4
MDgyNDIxMTQwOVowFjEUMBIGA1UEAwwLc2FtbHRlc3QuaWQwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC0Z4QX1NFKs71ufbQwoQoW7qkNAJRIANGA4iM0
ThYghul3pC+FwrGv37aTxWXfA1UG9njKbbDreiDAZKngCgyjxj0uJ4lArgkr4AOE
jj5zXA81uGHARfUBctvQcsZpBIxDOvUUImAl+3NqLgMGF2fktxMG7kX3GEVNc1kl
bN3dfYsaw5dUrw25DheL9np7G/+28GwHPvLb4aptOiONbCaVvh9UMHEA9F7c0zfF
/cL5fOpdVa54wTI0u12CsFKt78h6lEGG5jUs/qX9clZncJM7EFkN3imPPy+0HC8n
spXiH/MZW8o2cqWRkrw3MzBZW3Ojk5nQj40V6NUbjb7kfejzAgMBAAGjVzBVMB0G
A1UdDgQWBBQT6Y9J3Tw/hOGc8PNV7JEE4k2ZNTA0BgNVHREELTArggtzYW1sdGVz
dC5pZIYcaHR0cHM6Ly9zYW1sdGVzdC5pZC9zYW1sL2lkcDANBgkqhkiG9w0BAQsF
AAOCAQEASk3guKfTkVhEaIVvxEPNR2w3vWt3fwmwJCccW98XXLWgNbu3YaMb2RSn
7Th4p3h+mfyk2don6au7Uyzc1Jd39RNv80TG5iQoxfCgphy1FYmmdaSfO8wvDtHT
TNiLArAxOYtzfYbzb5QrNNH/gQEN8RJaEf/g/1GTw9x/103dSMK0RXtl+fRs2nbl
D1JJKSQ3AdhxK/weP3aUPtLxVVJ9wMOQOfcy02l+hHMb6uAjsPOpOVKqi3M8XmcU
ZOpx4swtgGdeoSpeRyrtMvRwdcciNBp9UZome44qZAYH1iqrpmmjsfI9pJItsgWu
3kXPjhSfj1AJGR1l9JGvJrHki1iHTA==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<KeyDescriptor use="encryption">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIDEjCCAfqgAwIBAgIVAPVbodo8Su7/BaHXUHykx0Pi5CFaMA0GCSqGSIb3DQEB
CwUAMBYxFDASBgNVBAMMC3NhbWx0ZXN0LmlkMB4XDTE4MDgyNDIxMTQwOVoXDTM4
MDgyNDIxMTQwOVowFjEUMBIGA1UEAwwLc2FtbHRlc3QuaWQwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCQb+1a7uDdTTBBFfwOUun3IQ9nEuKM98SmJDWa
MwM877elswKUTIBVh5gB2RIXAPZt7J/KGqypmgw9UNXFnoslpeZbA9fcAqqu28Z4
sSb2YSajV1ZgEYPUKvXwQEmLWN6aDhkn8HnEZNrmeXihTFdyr7wjsLj0JpQ+VUlc
4/J+hNuU7rGYZ1rKY8AA34qDVd4DiJ+DXW2PESfOu8lJSOteEaNtbmnvH8KlwkDs
1NvPTsI0W/m4SK0UdXo6LLaV8saIpJfnkVC/FwpBolBrRC/Em64UlBsRZm2T89ca
uzDee2yPUvbBd5kLErw+sC7i4xXa2rGmsQLYcBPhsRwnmBmlAgMBAAGjVzBVMB0G
A1UdDgQWBBRZ3exEu6rCwRe5C7f5QrPcAKRPUjA0BgNVHREELTArggtzYW1sdGVz
dC5pZIYcaHR0cHM6Ly9zYW1sdGVzdC5pZC9zYW1sL2lkcDANBgkqhkiG9w0BAQsF
AAOCAQEABZDFRNtcbvIRmblnZItoWCFhVUlq81ceSQddLYs8DqK340//hWNAbYdj
WcP85HhIZnrw6NGCO4bUipxZXhiqTA/A9d1BUll0vYB8qckYDEdPDduYCOYemKkD
dmnHMQWs9Y6zWiYuNKEJ9mf3+1N8knN/PK0TYVjVjXAf2CnOETDbLtlj6Nqb8La3
sQkYmU+aUdopbjd5JFFwbZRaj6KiHXHtnIRgu8sUXNPrgipUgZUOVhP0C0N5OfE4
JW8ZBrKgQC/6vJ2rSa9TlzI6JAa5Ww7gMXMP9M+cJUNQklcq+SBnTK8G+uBHgPKR
zBDsMIEzRtQZm4GIoHJae4zmnCekkQ==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
Location="https://samltest.id/idp/profile/SAML2/SOAP/ArtifactResolution" index="1" />
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://samltest.id/idp/profile/SAML2/Redirect/SLO" />
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://samltest.id/idp/profile/SAML2/POST/SLO" />
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
Location="https://samltest.id/idp/profile/SAML2/POST-SimpleSign/SLO" />
<SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"
Location="https://samltest.id/idp/profile/Shibboleth/SSO" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://samltest.id/idp/profile/SAML2/POST/SSO" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
Location="https://samltest.id/idp/profile/SAML2/POST-SimpleSign/SSO" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://samltest.id/idp/profile/SAML2/Redirect/SSO" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
Location="https://samltest.id/idp/profile/SAML2/SOAP/ECP" />
</IDPSSODescriptor>
</EntityDescriptor>

SAML IdP metadata document contains essential information required to establish the trust and connection from the service provider i.e SAML2 authenticator.

entityID="https://samltest.id/saml/idp" in the IdP metadata refers to the identifier of the remote SAML IdP.

KeyDescriptor use="signing" contains a X509 certificate which is used by the service provider to validate the signed SAML response sent by the SAML IdP.

SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" refers to the location where the user should be redirected to for the authentication purposes.

Firstly, import the SAML IdP public certificate in to the Curity Identity Server so that it could be used to verify the signed authentication response messages from the SAML IdP.

Copy the value of X509Certificate used for signing from the SAML IdP metadata and convert it to PEM format before adding to the Curity Identity Server.

bash
1234567891011121314151617
echo "MIIDEjCCAfqgAwIBAgIVAPVbodo8Su7/BaHXUHykx0Pi5CFaMA0GCSqGSIb3DQEB
CwUAMBYxFDASBgNVBAMMC3NhbWx0ZXN0LmlkMB4XDTE4MDgyNDIxMTQwOVoXDTM4
MDgyNDIxMTQwOVowFjEUMBIGA1UEAwwLc2FtbHRlc3QuaWQwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCQb+1a7uDdTTBBFfwOUun3IQ9nEuKM98SmJDWa
MwM877elswKUTIBVh5gB2RIXAPZt7J/KGqypmgw9UNXFnoslpeZbA9fcAqqu28Z4
sSb2YSajV1ZgEYPUKvXwQEmLWN6aDhkn8HnEZNrmeXihTFdyr7wjsLj0JpQ+VUlc
4/J+hNuU7rGYZ1rKY8AA34qDVd4DiJ+DXW2PESfOu8lJSOteEaNtbmnvH8KlwkDs
1NvPTsI0W/m4SK0UdXo6LLaV8saIpJfnkVC/FwpBolBrRC/Em64UlBsRZm2T89ca
uzDee2yPUvbBd5kLErw+sC7i4xXa2rGmsQLYcBPhsRwnmBmlAgMBAAGjVzBVMB0G
A1UdDgQWBBRZ3exEu6rCwRe5C7f5QrPcAKRPUjA0BgNVHREELTArggtzYW1sdGVz
dC5pZIYcaHR0cHM6Ly9zYW1sdGVzdC5pZC9zYW1sL2lkcDANBgkqhkiG9w0BAQsF
AAOCAQEABZDFRNtcbvIRmblnZItoWCFhVUlq81ceSQddLYs8DqK340//hWNAbYdj
WcP85HhIZnrw6NGCO4bUipxZXhiqTA/A9d1BUll0vYB8qckYDEdPDduYCOYemKkD
dmnHMQWs9Y6zWiYuNKEJ9mf3+1N8knN/PK0TYVjVjXAf2CnOETDbLtlj6Nqb8La3
sQkYmU+aUdopbjd5JFFwbZRaj6KiHXHtnIRgu8sUXNPrgipUgZUOVhP0C0N5OfE4
JW8ZBrKgQC/6vJ2rSa9TlzI6JAa5Ww7gMXMP9M+cJUNQklcq+SBnTK8G+uBHgPKR
zBDsMIEzRtQZm4GIoHJae4zmnCekkQ==" | base64 -D | openssl x509 -inform DER

Add the PEM certificate to Facilities -> Keys and cryptography -> Signing -> Signature verification keys.

After the certificate is added, it's details can be viewed in the UI.

Now with all the information available, configure the SAML2 authenticator in the Curity Identity Server.

Setting up the SAML2 Authenticator

First, create a new authenticator by giving it a name saml2 and selecting the Saml2 authenticator type.

Configure the authenticator to use samtestid as the SAML IdP

Take a look at the various configuration options supported by the authenticator

Configuration optionDescription
authentication-context-class-referenceThe URI of the authentication context class that the SAML authenticator requests the SAML IDP to enforce.
idp-entity-idThe SAML Entity ID of the remote SAML IdP (issuer of SAMLResponse).
idp-urlThe target IDP URL where SAML Authentication Requests are delivered to.
issuer-entity-idThe SAML Entity ID that the SAML authenticator (Service Provider) is registered at the SAML IdP (issuer of SAML AuthnRequest)
wants-assertion-signedIndicate whether the received Assertion must be signed.
wants-response-signedIndicate whether the received SAML Response message must be signed.
signature-verification-keyThe key to verify the signature of received SAML Response messages. Required if wants-assertion-signed or wants-response-signed is set to true.

The authenticator also accepts other options, that are not mandatory, for example:

  • If request-signing-key is set, then the SAML authenticator signs the SAML Authentication Request with the corresponding key.
  • Further, you can configure to request a certain NameIDFormat as part of the SAML Authentication Request by setting the nameid-format under request-options.
  • With the option force-authn set to always or if-requested-by-client, the SAML authenticator can enforce from the SAML IdP to ignore an active SSO session and authenticate the user.

In a secure setup, the SAML2 authenticator should be configured to sign the authentication requests and the SAML IDP should sign the authentication responses. However, it is possible to turn off signing temporarily for troubleshooting purposes by setting wants-assertion-signed, wants-response-signed to false and unsetting the request-signing-key.

Upload SP metadata

With the SAML2 authenticator, the SP metadata can be downloaded from the SAML2 authenticator's metadata endpoint. To establish the trust between the SAML2 authenticator and the SAML IdP, upload the authenticator SP metadata at SAML IdP metadata upload endpoint.

xml
12345678910111213141516
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="se.curity.example"
validUntil="2022-12-28T06:36:20.300Z">
<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="false"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
MIIDcjCCAlqgAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UEBhMCU0UxEjAQBgNVBAoTCUN1cml0eS5zZTEfMB0GA1UEAxMWc2UuY3VyaXR5LnRlc3Quc2lnbmluZzAeFw0xNTA1MjgwODU0MDBaFw0yNTA1MjgwODU0MDBaMEIxCzAJBgNVBAYTAlNFMRIwEAYDVQQKEwlDdXJpdHkuc2UxHzAdBgNVBAMTFnNlLmN1cml0eS50ZXN0LnNpZ25pbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIwAdmIh9sCCZkn7/gaP7B1Lyu9oo0FucfP+SuZ36SRfnVsDUSxRzQI3rvb7GdRv/4T/678ahaEnN2OIG7P1dqxJ9ArxbIDBtzswuTDjQDtnGXax+zEZOh3eqLW7yaOC6hz0JtWo91h7/1g9XGgrgJ4nPpXwCw9zFUnFirqizWsj2oXH/prUl1ASF60a2QcsW/CjzRRPMpcqEZdK73pateeQMTwrDlNIq+HaAj8FfhAdeMTzbGV0lEnxAhcalE1t3LMaRR2OyuGZmXcBEL0hSXGajCRwQQjON9s4oFUatVwnusdvQZg1oq0wH8yUfW4A8PGXqop5c4BnxgRnWvROg/AgMBAAGjcjBwMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLR6E141vi70+aKCeyo/Xg4DBN43MAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAQEAl8CX9fmD+NRggM7t3Cb9iPqGukIMQfk0mXgaUvBPFXP4GD3eISU2Rt+RdqBWlz8ij0q1aGYTkItrhim6fzIqznuooasbEP7bHTkV569I+kRX/G2Ew6o6EL8pGZdbVsjLtv0oJ7cnu1YOMdXgHIIuVHybs311b2ULjU3dIk4n6YvoxNmYVt9A0PbNFipsl2Hi3HjOrHQuvGzzNq9fxYfeLISl7lDTCA1dAGsDglS2OdVdQvYFQV3FKo2HqLzBIpcKdXZ0mx2iuz3/bCkhEBX5pRlb1m05b3MBRKigNfD2E5TZOKNn4Ynje6NOOX1Tae8syGam0Hl+PS3tD9L9norKlQ==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://localhost:8443/dev/authn/authenticate/saml2" index="0" />
</md:SPSSODescriptor>
</md:EntityDescriptor>

Now the configuration in the service provider and the IdP is completed to begin the testing of the SAML flow with the SAML2 authenticator.

SAML Authentication Flow Testing

To test the SAML flow as depicted in the following sequence diagram, mimic the application request step by navigating to the following URL in the browser or using OAuth Tools to kick start the flow.

bash
1
https://localhost:8443/oauth/v2/oauth-authorize?client_id=<client_id>&response_type=code&redirect_uri=<redirect_uri>&state=1653236518307-L6B&scope=openid&prompt=login&acr_values=urn:se:curity:authentication:saml2:saml2

Note

Replace the `client_id` placeholder with an actual value from the Curity Identity Server deployment. Also Ensure that the OAuth client has `saml2` authenticator in the allowed list of the authenticators.

On receiving the request, SAML2 authenticator generates a new SAML authentication request and redirects the user to the SAML IdP server SSO url for authentication.

SAML Authentication Request

xml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="https://localhost:8443/dev/authn/authenticate/saml2"
Destination="https://samltest.id/idp/profile/SAML2/Redirect/SSO"
ForceAuthn="false"
ID="_8HXfT3IfCo2MPGMvZyBW9SM702AL3LUC"
IssueInstant="2022-12-22T10:58:29.891Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0"
>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">se.curity.example</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="#_8HXfT3IfCo2MPGMvZyBW9SM702AL3LUC">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<DigestValue>d9CyYKzRtuNUPihtisNU+cBs0eykQsaWD4/j2ci+WKE=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>TxBekG4HAXL86dpvxsZZQ4yAU3cxUu1mMh5cL2025WNjmwbwNbcv/g3Qaago0Nb2iE14d2cy7dmX
9jVHHW80oS/HoIiBqqUvc7VBUVGqfoEQzMMDjPyV/2MclDdZtOjUayk+Oalsc6Zn9xTbtk0Q7b0z
Wa49U/ZyAvtc8puFPu8upBTdxVehp7k5VSRA22CwIgj4ImdDQRZJt/sRg9DgXgo4hmDcgneDUZy/
8maCDVlM+tpe9AMRmm4We4wgN7spUhYGtylIKGqBag2+7A5xgrVZG0QdskMy83BYeeKLmDLZMp+b
5HRIkhepxYEjMjSbGMTWGfVIVCzJMJDlyzTmYw==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIDcjCCAlqgAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UEBhMCU0UxEjAQBgNVBAoT
CUN1cml0eS5zZTEfMB0GA1UEAxMWc2UuY3VyaXR5LnRlc3Quc2lnbmluZzAeFw0xNTA1MjgwODU0
MDBaFw0yNTA1MjgwODU0MDBaMEIxCzAJBgNVBAYTAlNFMRIwEAYDVQQKEwlDdXJpdHkuc2UxHzAd
BgNVBAMTFnNlLmN1cml0eS50ZXN0LnNpZ25pbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDIwAdmIh9sCCZkn7/gaP7B1Lyu9oo0FucfP+SuZ36SRfnVsDUSxRzQI3rvb7GdRv/4T/67
8ahaEnN2OIG7P1dqxJ9ArxbIDBtzswuTDjQDtnGXax+zEZOh3eqLW7yaOC6hz0JtWo91h7/1g9XG
grgJ4nPpXwCw9zFUnFirqizWsj2oXH/prUl1ASF60a2QcsW/CjzRRPMpcqEZdK73pateeQMTwrDl
NIq+HaAj8FfhAdeMTzbGV0lEnxAhcalE1t3LMaRR2OyuGZmXcBEL0hSXGajCRwQQjON9s4oFUatV
wnusdvQZg1oq0wH8yUfW4A8PGXqop5c4BnxgRnWvROg/AgMBAAGjcjBwMA8GA1UdEwEB/wQFMAMB
Af8wHQYDVR0OBBYEFLR6E141vi70+aKCeyo/Xg4DBN43MAsGA1UdDwQEAwIBBjARBglghkgBhvhC
AQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOC
AQEAl8CX9fmD+NRggM7t3Cb9iPqGukIMQfk0mXgaUvBPFXP4GD3eISU2Rt+RdqBWlz8ij0q1aGYT
kItrhim6fzIqznuooasbEP7bHTkV569I+kRX/G2Ew6o6EL8pGZdbVsjLtv0oJ7cnu1YOMdXgHIIu
VHybs311b2ULjU3dIk4n6YvoxNmYVt9A0PbNFipsl2Hi3HjOrHQuvGzzNq9fxYfeLISl7lDTCA1d
AGsDglS2OdVdQvYFQV3FKo2HqLzBIpcKdXZ0mx2iuz3/bCkhEBX5pRlb1m05b3MBRKigNfD2E5TZ
OKNn4Ynje6NOOX1Tae8syGam0Hl+PS3tD9L9norKlQ==</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<samlp:NameIDPolicy AllowCreate="true" />
</samlp:AuthnRequest>

Take a look at the various attributes of the authentication request

ID - A randomly generated Identifier.

AssertionConsumerServiceURL - The endpoint where the SAML IdP sends the SAML response.

Destination - The endpoint where the SAML request is delivered to.

IssueInstant - Timestamp of the authentication request generation.

Issuer - The entity ID of the service provider i.e., the SAML2 authenticator.

ProtocolBinding - It refers to the protocol that should be used by the SAML IdP to send the SAML response back to the service provider.

Signature - It contains the signature value of the authentication request and also contains the X509Certificate that is used to verify the signature. The X509Certificate in the authentication request must match with the certificate uploaded during the certificate exchange process.

After the user authentication is successful, the SAML IdP server will generate a SAML authentication response and post it via the browser to the URL provided in the AssertionConsumerServiceURL request attribute

SAML Authentication Response

xml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
<saml2p:Response Destination="https://localhost:8443/dev/authn/authenticate/saml2"
ID="_226a6602bda4c67a541d6bb4ed75f3cb"
InResponseTo="_8HXfT3IfCo2MPGMvZyBW9SM702AL3LUC"
IssueInstant="2022-12-22T11:02:45.372Z"
Version="2.0"
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://samltest.id/saml/idp</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#_226a6602bda4c67a541d6bb4ed75f3cb">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="xsd"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>VkGj7xOpdsxdIPXwkYryB5YkHAgdicYy1q4KnqoTJxU=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
ni9yu43qpkbrK2A/tvRGLxULL3lGN27wGj6vtakcnbw5pEtc02P5szIa/NrO5WrElWALaotl+CaHmWbw63PGPTPYz2XsKpJqiR9JVT467uq/rPqICNwem69VZip3YHMz8nTqd3ai7RJ/8MK2TN1WPoV5tvIHLkvnE2q2Y1uA/BLePIo4PzJZ92U0lNt2rgfI1cDgjYbUhaOXytBMDP8r8ulRDaVrdC5RiFkNjFmFIEZeZr3CC/BNcgHXh95mBY+FYg4oB/5jx2BHWrdYrVKKGB5BR6j9qMRvzhvYtSGx/ccZHDfkY7woS8A4MpO7dWgGm9pR1f0jDEjilQfBPW14lQ==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDEjCCAfqgAwIBAgIVAMECQ1tjghafm5OxWDh9hwZfxthWMA0GCSqGSIb3DQEBCwUAMBYxFDAS
BgNVBAMMC3NhbWx0ZXN0LmlkMB4XDTE4MDgyNDIxMTQwOVoXDTM4MDgyNDIxMTQwOVowFjEUMBIG
A1UEAwwLc2FtbHRlc3QuaWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0Z4QX1NFK
s71ufbQwoQoW7qkNAJRIANGA4iM0ThYghul3pC+FwrGv37aTxWXfA1UG9njKbbDreiDAZKngCgyj
xj0uJ4lArgkr4AOEjj5zXA81uGHARfUBctvQcsZpBIxDOvUUImAl+3NqLgMGF2fktxMG7kX3GEVN
c1klbN3dfYsaw5dUrw25DheL9np7G/+28GwHPvLb4aptOiONbCaVvh9UMHEA9F7c0zfF/cL5fOpd
Va54wTI0u12CsFKt78h6lEGG5jUs/qX9clZncJM7EFkN3imPPy+0HC8nspXiH/MZW8o2cqWRkrw3
MzBZW3Ojk5nQj40V6NUbjb7kfejzAgMBAAGjVzBVMB0GA1UdDgQWBBQT6Y9J3Tw/hOGc8PNV7JEE
4k2ZNTA0BgNVHREELTArggtzYW1sdGVzdC5pZIYcaHR0cHM6Ly9zYW1sdGVzdC5pZC9zYW1sL2lk
cDANBgkqhkiG9w0BAQsFAAOCAQEASk3guKfTkVhEaIVvxEPNR2w3vWt3fwmwJCccW98XXLWgNbu3
YaMb2RSn7Th4p3h+mfyk2don6au7Uyzc1Jd39RNv80TG5iQoxfCgphy1FYmmdaSfO8wvDtHTTNiL
ArAxOYtzfYbzb5QrNNH/gQEN8RJaEf/g/1GTw9x/103dSMK0RXtl+fRs2nblD1JJKSQ3AdhxK/we
P3aUPtLxVVJ9wMOQOfcy02l+hHMb6uAjsPOpOVKqi3M8XmcUZOpx4swtgGdeoSpeRyrtMvRwdcci
NBp9UZome44qZAYH1iqrpmmjsfI9pJItsgWu3kXPjhSfj1AJGR1l9JGvJrHki1iHTA==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
<saml2:Assertion ID="_0c108b70082c00bb8e87c6f984273a85"
IssueInstant="2022-12-22T11:02:45.372Z"
Version="2.0"
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
>
<saml2:Issuer>https://samltest.id/saml/idp</saml2:Issuer>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
NameQualifier="https://samltest.id/saml/idp"
SPNameQualifier="se.curity.example"
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
>
AAdzZWNyZXQxwC5k0J0IfFgkDMnIWcNlCeeJ4c7WwGaCqW2uRiREIb8b8xiz0B3AVOyH9BuklDYevaa/Ha2dMBNRwyow3E5mJ4Z0g/EoEUvUeziT0m0egUXKEw5gxA==</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData Address="27.58.10.4"
InResponseTo="_8HXfT3IfCo2MPGMvZyBW9SM702AL3LUC"
NotOnOrAfter="2022-12-22T11:07:45.376Z"
Recipient="https://localhost:8443/dev/authn/authenticate/saml2"
/>
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotBefore="2022-12-22T11:02:45.372Z"
NotOnOrAfter="2022-12-22T11:07:45.372Z"
>
<saml2:AudienceRestriction>
<saml2:Audience>se.curity.example</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement AuthnInstant="2022-12-22T11:02:45.365Z"
SessionIndex="_628a1436958ee3d65b4d62071417a9c2"
>
<saml2:SubjectLocality Address="27.58.10.4" />
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
<saml2:AttributeStatement>
<saml2:Attribute Name="urn:oasis:names:tc:SAML:attribute:subject-id"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>msmith@samltest.id</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="uid"
Name="urn:oid:0.9.2342.19200300.100.1.1"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue>morty</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="telephoneNumber"
Name="urn:oid:2.5.4.20"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue>+1-555-555-5505</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="role"
Name="https://samltest.id/attributes/role"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>janitor@samltest.id</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="mail"
Name="urn:oid:0.9.2342.19200300.100.1.3"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue>msmith@samltest.id</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="sn"
Name="urn:oid:2.5.4.4"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue>Smith</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="displayName"
Name="urn:oid:2.16.840.1.113730.3.1.241"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue>Morty Smith</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute FriendlyName="givenName"
Name="urn:oid:2.5.4.42"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue>Mortimer</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
</saml2:Assertion>
</saml2p:Response>

Take a look at the SAML response sent back to the SAML2 authenticator

ID - A randomly generated Identifier.

InResponseTo - It contains the ID of the SAML authentication request.

Issuer - The entity ID of the SAML IdP.

NameID - The subject of the authenticated user. Format of the NameID is urn:oasis:names:tc:SAML:2.0:nameid-format:transient

Audience - The entity ID of the service provider i.e., the SAML2 authenticator.

AttributeStatement - It contains the attributes of the authenticated user.

The SAML2 authenticator then processess the SAML response and after validation, adds the response attributes to the Curity Identity Server subject authentication attributes which then can be issued as claims. Please refer to Adding Claims from Authentication for more details on adding claims from authenticated attributes.

Info

The SAML2 authenticator can also be used as a dynamic authenticator. This means that its configuration can be sourced from different places than from the configuration settings. See Dynamic Authenticator with SAML for more information.

Known Limitations

  1. Only a single assertion is supported in the SAML response. Should the SAML IdP return multiple assertions then only the first one is consumed, and the rest are discarded.

  2. Encryption is not supported on any level.

Further Information

For further information about the SAML2 authenticator, refer to the product documentation.