SAML¶
The SAML protocol plugin is available for integrating the Identity Server with a Federation Server. As with all protocols, there is a request interface that is meant for a Service Provider or App (acting as a Relying Party) to integrate to, as well as a response interface that responds with SAML towards a Federation Server (acting as Service Provider towards the Identity Server, and as SSO server towards the Relying Party). This interaction is shown in the following sequence diagram:
Fig. 139 SAML Interaction Sequence
The SAML protocol of the Identity Server supports the generic SAML IDP initiated SSO flow, as well as an ADFS-specific IDP initiated SSO flow. In both cases the SAML POST binding is used.
To integrate the SAML protocol plugin, both the Service Provider (App) as well as the Federation Server need to be configured. This section will describe how the protocol works, how a Service Provider (App) can integrate, as well as how to setup a Federation Server using a generic SAML federation service, Ping Federate, and ADFS.
SAML protocol¶
SAML protocol request¶
The following parameters can be provided to the authentication endpoint of the the Authentication Service as part of a SAML protocol request. Parameters must be provided in the query string of a GET request. Unknown parameters will be ignored.
Parameter name | Description |
---|---|
serviceProviderId |
REQUIRED (unless client_id is provided), the Service Provider Id that the Service Provider is registered with at the Authentication Service |
forceAuthN |
OPTIONAL, when the value is “true” or when the parameter is provided, it will enforce a fresh authentication, even when the user already has an existing session with the Authentication Service from before |
acr |
OPTIONAL, one or more string values that specify which ACR’s may be used to authenticate the user with |
freshness |
OPTIONAL, provide the number of seconds that indicates the maximum allowed age of a previous successful authentication. If previous authentication existed that was older than the indicated freshness, re-authentication will take place |
target_url |
OPTIONAL, when provided, the value of the state-parameter is used as the value for the RelayState parameter in the SAML protocol response. See below. |
Tip
If the downstream application is an OAuth client that will be accessed via SAML, the serviceProviderId
can be omitted and the client_id
can be used.
SAML protocol response¶
The authentication result is embedded in a generated HTML-page that uses JavaScript to auto-POST to the Assertion Consumer Service URL (acs-url) of the configured Federation Server. The parameters are as follows:
Parameter name | Description |
---|---|
SAMLResponse | The Base64 encoded SAML Response message, that is constructed for the receiving Federation Server |
RelayState | The generated RelayState. In the case of a generic Federation Service type, this is set to the
Target URL of the Service Provider. It can be overridden by the value of the target_url
parameter in a SAML protocol request. In the case of adfs see RelayState |
Configuring the Authentication Service¶
In order for the Authentication Service to be able to communicate with a SAML Federation Server, the following must be configured:
- An authentication service profile
- A SAML protocol which is set as the one used by the authentication service profile
- A singing key that will be used to digitally sign the SAML message
See also
For information about how to create an authentication service profile, refer to the section about creating a new profile earlier in this guide.
Defining a SAML protocol¶
When configuring the SAML protocol settings, the Authentication Service needs to know about the receiving end of the communications, as well as how to assert protocol message protection through digital signatures. The information that is required about the receiving Federation Server includes:
- The Federation Server’s Entity ID
- The Assertion Consumer Service URL of the Federation Server, where a SAML Response message can be posted to
- The type of the Federation Server
For message protection, the SAML protocol needs to be configured with a signing key.
Finally, there are a number of settings that can tweak the assertion generation procedure. The details of these settings can be found below.
Configuring the SAML protocol¶
The following configuration snippet is a template on how to configure the SAML protocol section of an Authentication protocol:
...
<profiles>
<profile>
<type xmlns:auth="https://curity.se/ns/conf/profile/authentication">
auth:authentication-service
</type>
...
<protocol-id>${ID}</protocol-id>
...
<protocols>
<protocol>
<id>${ID}</id>
<saml>
<signing-key>${reference-to-signing-key-id}</signing-key>
<recipient-entity-id>${federation-service-entity-id}</recipient-entity-id>
<acs-url>${federation-service-acs-url}</acs-url>
<saml-federation-service-type>${federation-service-type}</saml-federation-service-type>
<saml-clock-skew>${saml-clock-skew}</saml-clock-skew>
<saml-assertion-time-to-live>${assertion-time-to-live}</saml-assertion-time-to-live>
</saml>
</protocol>
...
</protocols>
...
</profile>
...
</profiles>
...
Configuration Element | Default Value | Mandatory | Meaning |
---|---|---|---|
id |
N/A | true | The identifier of the SAML protocol configuration. Set this as the value for protocol-id to activate the protocol on the profile |
saml/signing-key |
N/A | true | Reference to a key in the signing key section of the crypto facilities |
saml/recipient-entity-id |
N/A | true | The SAML EntityId of the Federation Server that a SAML Response message is sent to |
saml/acs-url |
N/A | true | The URL where the SAML Response message is POSTed to (including scheme, hostname, port, and path) |
saml/saml-federation-service-type |
generic |
false | The type of SAML Federation Service that is used. Valid choices are genric or adfs |
saml/saml-clock-skew |
60 | false | The number of seconds that timestamps may vary, to allow for clock skew between sender and receiver, e.g. used when validating inbound message expiration. |
saml/saml-assertion-time-to-live |
300 | false | The number of seconds that is used to indicate how long an issued (outbound) SAML Assertion or Message is valid. |
saml/saml-message-time-to-live |
300 | false | The number of seconds that is used to indicate how long an inbound SAML Message is valid after it was issued. |
Templates¶
The SAML protocol uses the template plugins/protocol/saml/postback.vm
to generate the HTML page that auto-POSTs the
SAML Response message to the Federation Server. To change the template, create a file called postback.vm
in the directory <template_dir>/third-party/protocol/saml/postback.vm
and make any modifications that are needed.
For debugging, it can be helpful to disable the auto-post to give you a chance to inspect the message before it is sent to the federation server. To do this, create a file called globals.vm
in the <template_dir>/third-party-debug/base
directory. In this template, set the $debugRedirect
variable to true
like this:
#set ($debugRedirect = true)
This will cause an interstitial page to be shown that contains the SAML message (both the encoded and decoded version) as well as the relay state.

Fig. 140 SAML Debugging
Tip
This technique of adding a global.vm
template to third-party-debug
and setting $debugRedirect
can be used with any protocol, not just SAML.
Service Provider (App) integration¶
For a Service Provider (App), that depends on SSO from a Federation Server, integration is kept as simple as possible. The Service Provider is registered with the Identity Server, see the section on configuring Service Providers. Doing so, it is assigned a Service Provider Id.
When making a request to authenticate a user, the Service Provider (App) redirects the user to the Authentication endpoint of the Identity Server, identifying itself with its Service Provider Id as parameter in the request. The authentication process ensures that the Federation Server gets a SAML Assertion with information about the authenticated user, and when this is accepted by the Federation Server, the user is redirected back to the Service Provider (App).
That URL that the authenticated user is redirected to, can be either the target-URL as configured with the Authentication Service (or maybe even a default URL that is configured at the Federation Server), but it can also be established as part of the initial request to the authentication endpoint of the Authentication Service. This means that the RelayState is generated from the request parameters, and provided to the Federation Server. It is then up to the Federation Server whether it understands this though.
Federation Server integration¶
As the SAML protocol will issue a SAML Assertion and provide that in an unsolicited SAML Response message to the Federation Server, both services need to be introduced to each other. At its minimum, the Authentication Service needs to exchange its EntityId as well as the signing certificate with the Federation Server at the receiving end. The EntityId is defined by the server’s Environment Id.
See also
For information about configuring the Identity Server’s environment or the Crypto facility, refer to the sections Configuration Guide and Cryptography.
What follows, is information how to set up a PingFederate and ADFS Federation Server to be used by the Authentication Service.
PingFederate¶
The SAML integration protocol can be used with PingFederate from Ping Identity. In particular, the SAML 2.0 IdP-initiated Web SSO profile needs to be setup using a POST binding. The steps to do this are documented in the PingFederate manual, but consist of the following high-level steps:
Create a SAML 2.0 Identity Provider connection in PingFederate and an SP adapter that will integrate your app with PingFederate.
On the general connection information tab of the IdP connection
- Use the
Entity ID
that corresponds to theenvironment/name
as configured in the Identity Server. - Enter the
recipient-entity-id
that was configured in the Identity Server as theVirtual Server IDs
.
- Use the
In the IdP connection, enabled the IdP-initiated SSO profile but not any of the others.
When configuring browser SSO, enable the POST binding but not the others.
Import and select the certificate that was configured in protocol instance’s
saml/signing-key
setting when configuring the security credential to be used for the PingFederate connection.
You can verify that the connection works by accessing the Authentication Service’s authenticate endpoint for the profile that is configured with the SAML integration protocol.
AD FS¶
The SAML integration protocol can be used to use the Curity Identity Server as the authentication server in an AD FS environment. This is made possible by configuring the Curity Identity Server as a Claims Provider for the AD FS server.
Add the Curity Identity Server as a Claims Provider Trust¶
Enter claims provider trust data manually
Use AD FS profile
Enable support for the Web SSO protocol
Set the
Claims provider SAML 2.0 SSO URL
to be the authentication endpoint. I.e.https://localhost:8443/authn/authenticate
Use a
Claims provider trust identifier
that corresponds to theenvironment/name
as configured in the Curity Identity Server.Configure the certificate that corresponds to the
signing-key
configured in the Curity Identity Server.
Configure Claim Rules to pass through all claims that the Curity Identity Server sends¶
- Create a new Claim Rule and use the template
Send Claims Using a Custom Rule
. - Set the rule to be
c:[] => issue(claim = c);
Tip
Create a Claim Rule to passthrough all claims issued by the Curity Identity Server to a Relying Party
c:[Issuer == "se.curity"]
=> issue(claim = c);
Where se.curity
corresponds to the environment/name
as configured in the Curity Identity Server.
Tip
Set the default Claims Provider for a Relying Party from powershell
Set-AdfsRelyingPartyTrust
-TargetIdentifier "rp-entity-id"
-ClaimsProviderName @("se.curity")
Where se.curity
corresponds to the environment/name
as configured in the Curity Identity Server and rp-entity-id
is the configured identifier for the Relying Party.
RelayState¶
When using IdP initiated SSO with ADFS, the form parameter RelayState
is used. The value of the RelayState
is a URL encoded string with the following components.
Parameter name | Description |
---|---|
RPID | The id of the Relying Party at ADFS. The Curity Identity Server will send the Service Provider ID. |
wctx | A parameter for WS-Federation Relying Parties. The Curity Identity Server will add this if the query
parameter target_url is present in the authentication request.
The Curity Identity Server will also add any unknown parameters to the url as the query string. |
RelayState | A nested RelayState parameter that will be sent to SAML Relying Parties by ADFS.
The Curity Identity Server will pass all unknown parameters here. If the target_url is set, the RelayState will be the same as wctx.
The full string is url encoded. |
Examples
Sending an unknown parameter foo
-
Authentication request
https://login.example.com/authn/authenticate?serviceProviderId=app1&foo=bar
-
Result:
RelayState=RPID%3Dapp1%26RelayState%3Dfoo%253Dbar
-
Data sent from ADFS to SAML Relying Party
RelayState=foo%3Dbar
-
Sending both target_url and an unknown parameter foo
-
Authentication request
https://login.example.com/authn/authenticate?serviceProviderId=app1&foo=bar&target_url=https://localhost/ws-fed
-
Result:
RPID%3Dapp1%26wctx%3Dhttps%253A%252F%252Flocalhost%252Fws-fed%253Ffoo%253Dbar%26Relaystate%3Dhttps%253A%252F%252Flocalhost%252Fws-fed%253Ffoo%253Dbar
-
Data sent from ADFS to a WS-Federation Relying Party
wctx=https%3A%2F%2Flocalhost%2Fws-fed%3Ffoo%3Dbar
-
Data sent from ADFS to a SAML Relying Party
wctx=https%3A%2F%2Flocalhost%2Fws-fed%3Ffoo%3Dbar&RelayState=https%3A%2F%2Flocalhost%2Fws-fed%3Ffoo%3Dbar
Note
It is up to the application to handle the data received. Nor SAML nor ADFS specify the use of the data, but it could be used to for loading a specific endpoint in the RP, or similar.
-
SAML Logout¶
When using the SAML integration protocol, the integrating party can send SAML Logout Requests to logout the current authenticated session. The requests needs to conform to the SAML Single Logout Profile
of the Profiles for the OASIS Security Assertion Markup Language (SAML) V2.0
(Section 4.4)
Logout Request¶
The logout is initiated by sending a LogoutRequest
to <authentication-endpoint-path>/logout
, below is an example request.
<samlp:LogoutRequest ID="_df7af98a-e872-457e-9ab5-9337b3680c1b"
Version="2.0"
IssueInstant="2020-05-15T05:41:03.269Z"
Destination="https://login.example.com/saml/authn/authenticate/logout"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://fs.curityio.net/</Issuer>
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
xmlns="urn:oasis:names:tc:SAML:2.0:assertion">johndoe</NameID>
<samlp:SessionIndex>_b2d5fe1d-bbb0-4644-a315-32728197fe60</samlp:SessionIndex>
</samlp:LogoutRequest>
Curity Identity Server will validate that the Issuer
is the recipient-entity-id
of the protocol config, or one of the service-providers
defined in the profile. If the request is valid, a LogoutResponse
will be sent to the configured logout-service-url
.
Note
The SessionIndex
and NameID
parameters are ignored, all SSO Sessions will be terminated.
Logout Response¶
The LogoutResponse
will contain a status code, and will be signed with the configured signing-key
.
<saml2p:LogoutResponse Destination="https://fs.curityio.net/saml"
ID="_89a4fa60-209f-47af-ba65-1b2959d02d13"
InResponseTo="_df7af98a-e872-457e-9ab5-9337b3680c1b"
IssueInstant="2020-05-15T05:41:03.276Z"
Version="2.0"
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">se.curity</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="#_89a4fa60-209f-47af-ba65-1b2959d02d13">
<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#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>GgDl0PDpNIr/OEex0KMlmZdphDnHFJSHxuxkL5I8GTI=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>tfcHN<snip>zS3fqQ==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDc<snip>KlQ==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
</saml2p:LogoutResponse>
Session Index¶
The SAML SLO profile requires the SessionIndex
parameter to be sent in a LogoutRequest
. Curity Identity Server will just log out all browser sessions, and not take the sent SessionIndex
into account. Curity Identity Server will however echo the sent SessionIndex
in the LogoutResponse
.
Since some SAML Identity Providers might require the SessionIndex
, it is recommended to enable the setting include-session-index-in-response
.
Logout using serviceProviderId¶
A registered service-provider
can use the simplified logout method by simply issuing a GET
request with the query parameter serviceProviderId
. This will terminate the session(s) and send an unsolicited LogoutResponse
to the configured logout-service-url
.
Note
Not all SAML IdP support receiving unsolicited responses.