SAML Integration Guide
1. What Is SAML 2.0
SAML is a standard that addresses web-browser single sign-on (SSO). SAML 2.0 is an XML-based protocol that uses security tokens containing assertions to pass information about a principal (usually an end-user) between an Identity Provider and a Service Provider.
The SAML flow is shown in the diagram below:
The user via the UserAgent (e.g Browser) tries to access the SP
The SP checks the current authentication session of the user and:
If the user still has a valid session provides the user access to the service.
If the user does not have a valid session, it will generate a AuthNRequest and redirects the user to the IDP’s SingleSignOnService URL
The IDP checks the AuthNRequest and if valid ask the UserAgent to provide authentication details.
The UserAgent provided the authentication details to the IDP.
The IDP checks the user credentials and if valid generates a SAMLResponse containing a SAML Assertion about the user attributes.
The IDP sends the SAMLResponse (through the UserAgent) to the AssertionConsumerService url of the SP.
The SP validates the SAML Response and assertions and if valid provides the user access to the service.
2. Integration
2.1. Setup
For SAML Integration the Service Provider and the Identity Provider first need to exchange their endpoints and signing-certificates with each other. Usually, this is done by exchanging a SAML Metadata document. The metadata of Audkenni can be downloaded here. An example of the metadata document that a service needs to provide can be downloaded here:
2.2. Request
2.2.1. Providing information about the chained Related Party
In some cases, the Service Provider is also an IDP that received a request from other SPs (Relaying parties) and relies on Audkenni for the actual authentication. This scenario is seen in the picture below.
In this scenario, Audkenni mandates that this information, name of the RelatedPartyParty, is provided in the AuthnRequest as an extension attribute named audkenni:relatedPartyParty
, e.g.:
<audkenni:relatedPartyParty xmlns:audkenni="urn:audkenni">Example client</audkenni:relatedPartyParty>
An example full AuthnRequest would then look as follows:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="http://localhost:8080/saml/SSO"
Destination="https://idp-dev.audkenni.is/sso/SSORedirect/metaAlias/audkenni/idp"
ForceAuthn="false"
ID="a57h5jf2jdffa5553d58332jc831g7b"
IsPassive="false"
IssueInstant="2019-11-28T13:27:04.831Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">com:audkenni:spring:sp</saml2:Issuer>
<md:Extensions xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<audkenni:relatedPartyParty xmlns:audkenni="urn:audkenni">Example client</audkenni:relatedPartyParty>
</md:Extensions>
</saml2p:AuthnRequest>
2.2.2. Providing the login message
The message that the user receives during authentication (e.g. on his phone/app/nexus card) can also be provided in the AuthNRequest as an extension attribute named audkenni:signingMessage
, e.g.:
<audkenni:signingMessage xmlns:audkenni="urn:audkenni">Login to example client</audkenni:signingMessage>
An example full AuthnRequest would then look as follows:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="http://localhost:8080/saml/SSO"
Destination="https://idp-dev.audkenni.is/sso/SSORedirect/metaAlias/audkenni/idp"
ForceAuthn="false"
ID="a57h5jf2jdffa5553d58332jc831g7b"
IsPassive="false"
IssueInstant="2019-11-28T13:27:04.831Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">com:audkenni:spring:sp</saml2:Issuer>
<md:Extensions xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<audkenni:relatedPartyParty xmlns:audkenni="urn:audkenni">Example client</audkenni:relatedPartyParty>
<audkenni:signingMessage xmlns:audkenni="urn:audkenni">Login to example client</audkenni:signingMessage>
</md:Extensions>
</saml2p:AuthnRequest>
If no signingMessage is provided, the user will receive the message “Login to Audkenni”.
2.2.3. Influencing the login flow
The login flow the user experiences can be influenced by setting a “RequestedAuthnContext“ in the AuthnRequest. At the moment the following contexts are supported
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
In this case, the default login flow would be presented in which the user can choose the authentication method
urn:oasis:names:tc:SAML:2.0:ac:classes:SmartcardPKI
In this case, only the nexus personal card authentication option is shown
urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract
In this case, only the Sim card authentication option is shown
An example AuthNRequest where for instance the sim card option is enforced looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="http://localhost:8080/saml/SSO"
Destination="https://idp-dev.audkenni.is/sso/SSORedirect/metaAlias/audkenni/idp"
ForceAuthn="false"
ID="a57h5jf2jdffa5553d58332jc831g7b"
IsPassive="false"
IssueInstant="2019-11-28T13:27:04.831Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">com:audkenni:spring:sp</saml2:Issuer>
<md:Extensions xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<audkenni:relatedPartyParty xmlns:audkenni="urn:audkenni">Example client</audkenni:relatedPartyParty>
<audkenni:signingMessage xmlns:audkenni="urn:audkenni">Login to example client</audkenni:signingMessage>
</md:Extensions>
<saml2p:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract</saml:AuthnContextClassRef>
</saml2p:RequestedAuthnContext>
</saml2p:AuthnRequest>
2.3. Response
NameID
The social security number of the user is set as the NameID in the authentication response
attributes
In the SAML Assertion, the following attributes are returned
nationalRegisterId
The social security number
certificate
The certificate generated by the authenticator as a result of the user authentication
As a reference, a complete SAML Response looks as follows:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="s2cfc8184b0da6eda25d8387069c56e04c371a58f5"
InResponseTo="a36gea5c57j4d4a44g48ce7935bdcfd"
Version="2.0"
IssueInstant="2019-11-28T14:11:39Z"
Destination="http://localhost:8080/saml/SSO">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">idp-audkenni</saml:Issuer>
<samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
Value="urn:oasis:names:tc:SAML:2.0:status:Success">
</samlp:StatusCode>
</samlp:Status>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="s23714053df35586d1af847599c20670e2763ef42a"
IssueInstant="2019-11-28T14:11:39Z"
Version="2.0">
<saml:Issuer>idp-audkenni</saml: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="#s23714053df35586d1af847599c20670e2763ef42a">
<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>SqUIJ1nnASEhTYa2xVWtnuP36wTgABsLaljgE/qKqr0=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
ZbVFAqIoNrxgyxFjZPP5lWsPhbosUuGlNV/dDVWpxDEDJFuVwDBdcmQTWzlu8ZyOIwL+xAXIm+Pg 5QnURv7IkLGvkcgpWF7roAm5pw2Wi7Q9xoIVpQcUqdLn4Ja8P/FM9m0TuzkdwzPmxLKzBn1sq1Op UegBFYETlb8q+JhsC4Qd/wvYgriGiMIE95y7jWGHYbf+AhptXqpLhPYFjGtc8KxDbIe1pFpA61+J S8yDANcHV5GqklvhZNAS/Ytjtr+gejo1rxjaiQP9r3AIoQZmNrZPvlj/R58cEgc+SlrETao9kAA4
6uoQA0mY36QVArBsjnrk2ljn400lJM4Ylr37HPbbXug8W2xFvq8XmlxgpREaQSmKp2MZCzMv3few /vgHCOUzctz4UYhxYGsjJnGS9R61ipCHDiXtb4xSOuYPNG+bOO8rdS41YssdnHIHBmrP7jp+2vMu 7R6sGNeksJD2WHF+JZUDgqkiTyp4HgpXiBEggGN7Xz5vSKMSos2ERW32
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIID/zCCAmegAwIBAgIEfaPy4jANBgkqhkiG9w0BAQsFADAwMQswCQYDVQQGEwJJUzERMA8GA1UE ChMIQXVka2VubmkxDjAMBgNVBAMTBXNhbWwyMB4XDTE5MTExNTA5MTUxNFoXDTI5MTEyMjA5MTUx NFowMDELMAkGA1UEBhMCSVMxETAPBgNVBAoTCEF1ZGtlbm5pMQ4wDAYDVQQDEwVzYW1sMjCCAaIw DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKe912NIWn2B+axdhdESiFMnIK23dJ8TCV/Tcl9X
iT1Sgc8WTSNU9a2RZoEaC7pR+3q7CQXJZ3LenCO77PwwB1PFioXRM7DY7v2C6XorBT1TmQYTyNDn zsgHCoxLAPBEkpFN9MRtiaQedzTC7ZaR36RhsGNdQVVPXSMgbSCNamesDWgqC4D1CiV/d02DFLXS Kr3D4/Q5ZU/IA8+tMvEv6nwvhgYBcBElmtaZZSA7QZbR2ogziMUZq4VlxXcu9n+wBkvQ6RYBRf4e
5SumJOPAG2KOH7sCAqfu28kxisrtuP4DUvx1cY7u2GYmrY11sf96DwLoAn/9IAADC1nY8ehKi1k1 y84xwq/ovyfYozW3wkpHb5TQhiAq5rFbiUfFGmfqMH0kIL7WRAG7eVJ45S9nXYdpYvvdkR94oSfL uS9VOoBggCHXokNKfntbx0oX2QSGzSpmRTrJ2efDIVUDeiIyaIOkoc9c/AanNfkdbkF0z9vx3SB3
sM3ec/y/Tl5u6fz+FwIDAQABoyEwHzAdBgNVHQ4EFgQUpw9ZOOWOtzE8CgGZhiWSJVLKonIwDQYJ KoZIhvcNAQELBQADggGBAAAMv6DGLxe6exRRzJ6ygBzSpiUgoRBAWPBERB9JEHeuV193UCoLkz12 PJ3wYQQPUr4Fwz/2BnXXo0Hx0cZ5MFF4+oQSvuLCIqAJBaXUnlYPVvnQ0z6df5QNnb59wUsci+gV
1Es9kyPPS2CeDynvLEdFjjKeVuoDI6rvNgxkA6+6oUwhQLhB0qMjjciuMs5S0pJuif0hJ3EwGf7V 0XU4DAtk5xlhFyJj7CpYmgjbR/2FEYpqiK4W99VJo+BQu8/X1GsOHm1JzJ3Y3QrrUWWaE1FITxyr 3sZs+psmzW/yj3gDuzvOcOLW5CjwXa9o5W6gSE8jI/aD0H+0yUjYIEFJzLxa9qBYjGolpB4vOTFy
YEyrsTlWtaSZXSALefFDwIDeLpblunwKK0FrsQkLMPGrOejGwOcO7MR1VgjObqZ9EYtuaJ6tFDzK vs6HXpV73NpvxT6iGd1R7/r+T25mo1yMr90GuJrH5QrSpz6gFB7BN3YZH41HUwKsw/0pdTB4UdZf fQ==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
NameQualifier="idp-audkenni">10101303369</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="a36gea5c57j4d4a44g48ce7935bdcfd"
NotOnOrAfter="2019-11-28T14:21:39Z"
Recipient="http://localhost:8080/saml/SSO" /></saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2019-11-28T14:01:39Z"
NotOnOrAfter="2019-11-28T14:21:39Z">
<saml:AudienceRestriction>
<saml:Audience>com:audkenni:spring:sp</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2019-11-28T14:11:38Z"
SessionIndex="s24e3d69c700574c47516412d3a2a92b3a3529c601">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="certificate">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xs:string">
MIIIBQYJKoZIhvcNAQcCoIIH9jCCB/ICAQExDTALBglghkgBZQMEAgEwPQYJKoZIhvcNAQcBoDAELgBMAG8AZwBpAG4AIAB0AG8AIABlAHgAYQBtAHAAbABlACAAYwBsAGkAZQBuAHSgggV7MIIFdzCCBF+gAwIBAgICGwgwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAklTMRMwEQYDVQQFEwo1MjEwMDAyNzkwMRYwFAYDVQQKEw1BdWRrZW5uaSBlaGYuMSQwIgYDVQQLExtVdGdlZmFuZGkgcHJvZnVuYXJza2lscmlramExJjAkBgNVBAMTHUZ1bGxnaWx0IGF1ZGtlbm5pIHByb2Z1biB0ZXN0MB4XDTE5MTAxNTE4NDAwNloXDTI0MTAxNTE4NDAwNlowgYUxCzAJBgNVBAYTAklTMRYwFAYDVQQLEw1laW5rYXNraWxyaWtpMRQwEgYDVQQLDAtBdcOwa2VubmluZzEXMBUGA1UECxMOMjAxOTEwMTUxODM5MDYxEzARBgNVBAUTCjAxMDEzMDMzNjkxGjAYBgNVBAMMEUdlcnZpbWHDsHVyIEFzw61hMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt8ZeWwp2W7h81FjX5IMP65qutsiqag/Hiv7awEgmMG+8uyr79pVmYxTj5zSwEi1TedRj9ZsdrtHGJTiY+uCtw+MoUtjHZKguMfHAQDrY3YfMLVbdJ43g+wjmjzhgDmhMUZcvjdoHk0zWQW8CODttyCMysSafR8EF3B7g5W7ZR+bMub7/OiR2qPUW8Aau/wHxkKW5NIOgejHZx53W7YLpXZJHomIRLY/WbdhTBCBcpdi/Lbndlfn2A/Xapp7cnhFNhbYuIqVr+xwOBezHAoFAzqkBaIjyI8WrpW15y6c49xTFZFbYAccJJwsBeFA70xKUVPy6izkWYIURr5rv4lSzwwIDAQABo4IB6jCCAeYwDAYDVR0TAQH/BAIwADCBnwYDVR0gBIGXMIGUMIGRBghggmABAodnAjCBhDBFBggrBgEFBQcCAjA5GjdUaGlzIGNlcnRpZmljYXRlIGlzIGludGVudGVkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuMDsGCCsGAQUFBwIBFi9odHRwOi8vY3AuYXVka2VubmkuaXMvZnVsbGdpbHRhdWRrZW5uaXByb2Z1bi9jcDCBgQYIKwYBBQUHAQEEdTBzMCgGCCsGAQUFBzABhhxodHRwOi8vb2NzcHBpbG90LmF1ZGtlbm5pLmlzMEcGB2CCYAIBYwaGPGh0dHA6Ly9jZHAuaXNsYW5kc3JvdC5pcy9za2lscmlraS9mdWxsZ2lsdGF1ZGtlbm5pcHJvZnVuLnA3YjALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHwYDVR0jBBgwFoAUZqx2fGCNK2vn0hARkP0s2vwRNCEwTgYDVR0fBEcwRTBDoEGgP4Y9aHR0cDovL2NybC5hdWRrZW5uaS5pcy9mdWxsZ2lsdGF1ZGtlbm5pcHJvZnVuX3Rlc3QvbGF0ZXN0LmNybDAdBgNVHQ4EFgQUXky+Lx+aCvaArmShdKS4uTHhgiMwDQYJKoZIhvcNAQELBQADggEBAITUMwf15Dz+spcWdSpDEsfdG0C0miT5/k1aBvFvY+OL3b0J+dYXQwuzwsaXdx1pD7DPUHSGmpcrRKs8dbzmLzezS19hX4+BEMrEMu1t48gOST9sxwlEK2SchBo/xNm4r68w4opty2ILEq+Ngh2g+GnLGzXq8Yb+7GmgOouqSjGHJQKF8WPMbLjrlFSPNN5/MuXaULT5kWtupp0qqdwm2NIoU5yoF9uwSndeVCZnynhyw9mhf6l3vqYN67srHwbAIP3jQRdyBqavbdZF6Q3W+22HlsElPLtZuB0jVh5MNCuqdSqGEZoJ7L6oooQNOFC0Ed4sr5N5B7aOaPSl4BF2yywxggIeMIICGgIBATCBjzCBiDELMAkGA1UEBhMCSVMxEzARBgNVBAUTCjUyMTAwMDI3OTAxFjAUBgNVBAoTDUF1ZGtlbm5pIGVoZi4xJDAiBgNVBAsTG1V0Z2VmYW5kaSBwcm9mdW5hcnNraWxyaWtqYTEmMCQGA1UEAxMdRnVsbGdpbHQgYXVka2VubmkgcHJvZnVuIHRlc3QCAhsIMAsGCWCGSAFlAwQCAaBlMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwGAYKKoZIhvcNAQkZAzEKBAiMTwzX0b04jzAvBgkqhkiG9w0BCQQxIgQgVvR11EW4S1uYeqj2Lf8ToJvMme0qeg8DpuIe0vH6SSkwCwYJKoZIhvcNAQEBBIIBAGDtX8QGBg0SRjcB99kTLpO6ulS5DGWXeWPANcMjC1lyF4FYFlv62PdPCnpeKB4UnecHsvJKz0FhFdXOzJNQyOh0r03MkJtaWGyWbbXVfVijoBsTt1jRLpeZLX3NvhMqEAtqTAAl3LWMCmPjC4Ykz+HftsgVEJD3nKLWZD6niilj6l+d2u+c0uMLp5rk6UNGzm5zn73QEiLTN9JoQ2QAd/L+nTUeLEoPpjdKREczqzwBWpL/q6BK2458xZrorKIr4N+jFQgZKxg862jjxpLfcHfBIn/AZmxU5S7J8ZFFONshx28QU5XkBZmw/YEyb7qtZflfBRuxumpFLx77bhseQZI=
</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="nationalRegisterId">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xs:string">0101303369</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>