A full description of SAML2 is out of scope of this document. See the SAML2 core, binding, and metadata specifications and other internet resources for details.
The SAML2 Identity Provider (IDP) must support Service Provider (SP) initiated authentication, HTTP-REDIRECT binding using DEFLATE encoding, and HTTP-POST binding. Such support is indicated by the following XML elements in the Identity Provider's metadata, specifically underneath the IDPSSODescriptor element:
<SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://uat.signin.mycas.org.uk/idp/profile/Shibboleth/SSO"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://uat.signin.mycas.org.uk/idp/profile/SAML2/POST/SSO"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://uat.signin.mycas.org.uk/idp/profile/SAML2/Redirect/SSO"/>
Parameters
As well as the parameters described in Base Provider Parameters, the following must be set in the params object.
Name | Type | Description | |
---|---|---|---|
signAuthnRequests | boolean, required | True if AuthnRequests are to be signed with the SP's private key, false otherwise. Requests to IDPs that do not support signed requests will fail if a signature is supplied, rather than simply ignoring the signature. Default: false. | |
identityProviderMetadata | Map, required | A map containing details about the IDP. One of idpMetadataUrl or idpMetadataFilePath must be supplied. | |
- | idpMetadataUrl | String (URL), required | URL to the IDP's metadata. e.g. https://host.co.uk/idp-metadata.xml Exclusive with idpMetadataFilePath. |
- | idpMetadataFilePath | String (File), required | Path to a file containing the IDP's metadata. e.g. E:\dir\idp-metadata.xml Exclusive with idpMetadataUrl. |
- | entityId | String, required | The entityId of the root IDPSSODescriptor element to extract information from as there may be several defined within the IDP metadata. e.g. https://host.co.uk/idp/shibboleth |
- | idpCertificateAlias | String, required | If the IDP's public key is not present in the IDP metadata and idpCertificateAlias is supplied it will attempt to extract the IDP's public key from the global keystore using this alias. |
- | minHttpRefreshDelay | Integer, optional | Default: 15 minutes (900000ms). The minimum period of time in milliseconds that metadata retrieved via URL is refreshed. Only applicable when metadata is retrieved via the spMetadataUrl property |
- | maxHttpRefreshDelay | Integer, optional | Default: 15 minutes (900000ms). The maximum period of time in milliseconds that metadata retrieved via URL is refreshed. Only applicable when metadata is retrieved via the spMetadataUrl property |
- | httpRefreshDelayFactor | Float, optional | Default: 0.99 The delay factor used to compute the next refresh time. The delay must be between 0.0 and 1.0, exclusive |
serviceProviderMetadata | Map, required | A map containing details about the SP. One of spMetadataUrl or spMetadataFilePath must be supplied. | |
- | spMetadataUrl | String (URL), required | URL to the SP's metadata. e.g. https://host.co.uk/sp-metadata.xml Exclusive with idpMetadataFilePath. |
- | spMetadataFilePath | String (File), required | Path to a file containing the SP's metadata. e.g. E:\dir\sp-metadata.xml Exclusive with idpMetadataUrl. |
- | entityId | String, required | The entityID of the root EntityDescriptor element to extract information from. e.g. http://demo.gossinteractive.com |
- | assertionConsumerServiceIndex | Integer, optional | Can identify a particular AssertionConsumerService entry in the SP metadata. If not supplied, defaults to the AssertionConsumerService marked with default="true". This allows a SP metadata file to contain multiple AssertionConsumerService entries rather than having to have a separate SP metadata file per environment. For example a single service provider XML file (and certificate) may be used for all non-live sites for a client (e.g. QA, DEV, UAT, etc.) rather than a new file per environment |
- | spKeyPairAlias | String, required | Alias of the public/private key pair located in the global key store, the public key of which would have been supplied to the owners of the IdP. The key pair is used to sign AuthnRequests, and decrypt encrypted assertions received from the IdP. |
- | spKeyPairPassword | String, required | The password to use when attempting to gain access to the service provider's key pair. Default when not supplied is changeit. |
- | minHttpRefreshDelay | Integer, optional | Default: 15 minutes (900000ms). The minimum period of time in milliseconds that metadata retrieved via URL is refreshed. Only applicable when metadata is retrieved via the spMetadataUrl property |
- | maxHttpRefreshDelay | Integer, optional | Default: 15 minutes (900000ms). The maximum period of time in milliseconds that metadata retrieved via URL is refreshed. Only applicable when metadata is retrieved via the spMetadataUrl property |
- | httpRefreshDelayFactor | Float, optional | Default: 0.99 The delay factor used to compute the next refresh time. The delay must be between 0.0 and 1.0, exclusive |
userProfileAttributeMapping | Map, required | Maps assertion attributes as returned by the IdP in its AuthnResponse (left) to the Auth worker's UserProfile class fields (right). Only the UNIQUEID field is required. Case insensitive. { | |
supplyAuthContext | Boolean, optional | Default: true If false the context won't be sent to the IdP | |
authComparisonType | String, optional | Default: minimum Sets the RequestedAuthenticationContext. One of minimum, exact, maximum or better | |
contextClasses | Array <strings>, optional | Default: Password The list of AuthnContextClassRefs. If a string doesn't contain a colon then "urn:oasis:names:tc:SAML:2.0:ac:classes:" is prepended For example ["Password", "urn:federation:authentication:windows"] |
Example
{
"providerName": "examplesaml2provider",
"providerDisplayName": "Example SAML2 Provider",
"type": "saml2",
"userPrefix": "EX_",
"params": {
"identityProviderMetadata": {
// ID of the IDPSSODescriptor identifying the SAML2 endpoint
// we're interested in.
"entityId": "https://idphost.co.uk/idp/shibboleth",
// URL from which the IdP metadata will be loaded from.
// Could also be supplied as a local file via the exclusive
// idpMetadataFilePath parameter as below for the SP.
"idpMetadataUrl": "https://idphost.co.uk/idp-metadata.xml",
// Alias for the IdP's public certificate, as stored in the
// Auth worker's cacerts key store.
"idpCertificateAlias": "idphost.co.uk_cert"
},
"serviceProviderMetadata": {
// ID of the EntityDescriptor within the service provider
// metadata.
"entityId": "http://test.gossinteractive.com",
// File path to the SP metadata file.
// Could also be supplied as a URL to a file via the exclusive
// spMetadataFileUrl parameter as above for the IdP.
"spMetadataFilePath": "E:/sp/service-provider-metadata.xml",
// Alias for the SP's key pair as stored in the Auth worker's
// cacerts key store.
"spKeyPairAlias": "http://test.gossinteractive.com_keypair"
},
"userProfileAttributeMapping": {
"mapping": {
"UCRN": {
"mappings": ["UNIQUEID", "UCRN"]
},
"TITLE": {
"mappings": ["TITLE"]
},
"FNAME": {
"mappings": ["PREFERREDNAME", "FORENAMES"]
},
"MNAME": {
"mappings": ["MIDDLENAME"]
},
"LNAME": {
"mappings": ["SURNAME"]
},
"EMAILADDRESS": {
"mappings": ["EMAIL"]
}
}
}
}
}
Identity Provider Metadata
Details about the identity provider (the third party) are stored in a structured XML format defined in the SAML2 Metadata Specification. The IdP metadata supplies information about what bindings are supported, the URLs associated with those bindings, supported identifier formats, public certificates, and so on.
Service Provider Metadata
Details about the service provider (the Auth worker) are stored in a structured XML format defined in the SAML2 Metadata Specification. Here's an example, although the full X509Certificate values have been trimmed for brevity:
<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://demodev1.gossinteractive.com" ID="pfx4fcd1234-2cf3-d4d0-1234-819e7eb21234">
<md:SPSSODescriptor 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>MII...PzE=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MII...PzE=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://demodev1.gossinteractive.com/apiserver/auth/http/reentry" />
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://demodev1.gossinteractive.com/apiserver/auth/http/reentry" index="0" isDefault="true" />
</md:SPSSODescriptor>
</md:EntityDescriptor>
Setup
Two things must be known before starting:
- The subsite URL for the client site which is used as the SAML2 entityID and the alias of the corresponding key pair in the cacerts file. Referred to as the 'entityID' from here on.
- The URL to the auth worker's reentry method for all non-live environments. For example: http://www.{{CLIENT}}-dev/apiserver/auth/http/reentry
Two files are needed before starting:
- A default java cacerts file from the current version of the API Server. Acquire one from: ${APIServer}/java7/jre/lib/security/cacerts
- A service provider metadata file. See the template above.
Check the following:
- The type of user profile on the current iCM installation. This is relevant to creating the user attribute to user profile mappings later on. Is it flat (EMAIL) or nested (USER.CONTACT.ETC.EMAIL)? What are the field names (FORENAME or FIRSTNAME, etc)?
- If a generic SAML2 provider rather than MyGovScot, check that the identity provider metadata specifies support for AuthnRequest and HTTP-Redirect/HTTP-POST bindings (described right at the top of this page)
Key Pair Generation - Self Signed Certificates
Unlike TLS, where browsers use a list of trusted certificate authorities, SAML federation can use self-signed certificates because the trust can be established explicitly. That is, you can send your public key (part of the certificate) to your partner through a different channel, such as email. The partner then installs it and explicitly trusts that certificate only. There's no need for them to trust a third-party CA. This kind of trust can use self-signed certificates without worry.
The following details how to generate a self-signed certificate using KeyStore Explorer.
- Rename the cacerts file (previously copied from the API Server's Java JRE install) to
{{PREFIX}}_cacerts , where{{PREFIX}} is the environment. This is so we can tell which environment the cacerts file is for use with, e.g.DEV_cacerts ,PROD_cacerts , etc. Note that by renaming the files you will need to update thecacertsOverridePath in the Worker Configuration Properties - Open the
{{PREFIX}}_cacerts file with KeyStore Explorer - Generate a self-signed key pair (certificate and private key) with a password of 'changeit' using KeyStore Explorer and store it in the cacerts file
- Click the "Generate Key Pair" button
- Hit 'OK' to generate the key
- Set a two year validity period
- Click the address book icon to set the certificate information. Enter the entityID (ie the main subsite URL for the client site as noted in the prerequisites) as the CN. See below for an example for gossdevteamweb1:
- CN=http://gossdevteamweb1.storm50.com
- OU=Development
- O=GOSS Interactive Ltd
- L=Plymouth
- ST=Devon
- C=UK
- E=someone@mywebsite.com
- Set the key pair alias to the entityId/CN. This alias name will need to be referred to in the provider configuration file later
Setting up Service Provider Metadata, Provider Configuration, Server Files
- Export the certificate from the key pair as X501
- Right click the new key pair entry, then Export, then Export certificate chain
- Leave everything as default
- Set the export path, and hit export
- Keep this file to hand
- Populate the skeleton service provider metadata file
- Replace
{{ENTITYID}} with the entityId - Replace
{{PUBLIC_KEY}} with the (formatted) public key as exported in the previous step- Open the .cer file exported in the previous step
- Remove the
-----BEGIN CERTIFICATE----- and-----END CERTIFICATE----- lines from the top and bottom of the file - Replace the
{{PUBLIC_KEY}} placeholders with the resulting newline delimited base 64 text
- Replace
{{CLIENT_URL}} within the AssertionCustomerService element appropriately, such that the 'Location' attribute contains the URL to the Auth worker's /http/reentry method- If adding more than one AssertionCustomerService (eg creating a single non-live service that supports multiple non-live environments such as DEV, QA, etc.)a dd in additional AssertionCustomerService elements, setting the additional Location and index to previous+1 each time, ensure that only one AssertionCustomerService entry has isDefault="true" set, and if using a non-default AssertionCustomerService then the provider setting serviceProviderMetadata.assertionConsumerServiceIndex (in the API Server configuration) must be set to the index to use on the server matching that URL
- Replace
- To install the Live or UAT service at the SAML2 IDP end, send an email to your contact with a zip file attachment containing the service provider metadata and the previously exported public certificate
- Populate the API Server configuration file with the provider details described at the start of this article
- Put the cacerts file containing the key pair under
${APISERVER}/data/auth/cacerts . If the cacerts file has been renamed for each environment (as recommended), egDEV_cacerts ,LIVE_cacerts etc, then the worker level configuration propertycacertsOverridePath for that environment will also need to be set to point to the rename file file, eg${APISERVER}/data/auth/LIVE_cacerts - Put the service provider metadata file under
${APISERVER}/data/{{PROVIDERNAME}}/[DEV|LIVE]_serviceProviderMetadata.xml - Update the API Server configuration and resend