/ single-sign-on

Single Sign On with SAML

If you’ve worked with any B2B firms who provide Software as a services to clients in a multi tenanted environment, you might have heard of terms like Single Sign on, SAML. This write up will briefly explain what each of these terms are.

Let’s assume that we have a cloud software as a service provider like Orielly and we are working for a firm called Foo & Bar, now Foo & Bar wants all of its users to use Orielly to learn new and interesting stuff in technology. Given this use case, Foo & Bar will have a lot of users and if Orielly wants to manage all the users of Foo & Bar its gonna be a very cumbersome task, also note that Foo & Bar might not be the only clients of Orielly.

Let’s say that Orielly takes the burden of managing the user information on its side, with its huge database containing user information. The following problems arise

  1. Foo & Bar will have IT administrators who are responsible for granting access to infrastructure and additional software for the employees, now let’s assume that an employee A who got access to Orielly at some point in time when he joined, is resigning today. The administrator would have to explicitly revoke access of A to Orielly, failing which A might still continue to use Orielly even though he’s not an employee of Foo & Bar.
  2. From the user/employee’s perspective, he/she will have to remember her account details because the details for Orielly will obviously be different from that of what he/she got when he/she joined Foo & Bar.
  3. From Orielly’s perspective, let’s assume that their database got hacked or some evil DB administrator took a dump of the production data to local, the impact area is very huge in this case because the Service provider(Orielly) is leaking confidential information of many users which are spread across clients.

This is where Single Sign On’s use case fits appropriately.

Actors Involved in Single Sign On

  1. The client(Foo & Bar).
  2. The client’s user base (Active directory).
  3. Identity Provider (Keycloak/Okta).
  4. The employee of the client(Employee A).
  5. Service Provider(Orielly).

The main actor among the ones listed above is the Identity Provider commonly abbreviated as IDP, who will have access to the Client’s user base like Active Directory. Given this setup let’s say that the user Employee A wants to go to Orielly, he can do so via two ways

Service provider initiated SSO

  1. Go to Orielly directly using an URL like foo.bar.orielly.com or something similar, using this domain name the service provider can redirect to the client’s IDP. There are other ways to redirect to the client’s IDP and this process is called realm discovery.
  2. Once the user lands on to the IDPs page, the IDP might ask the user to key in his/her credential based on whether he/she was previously logged in or not.
  3. Once the authentication at the IDP is successful the IDP generates a token called SAML token(details will follow), redirects the user to the service provider’s authentication page with the token as payload
  4. Upon the token verification at the service provider end, the user will be able to access the services of the service provider.

Identity provider initiated SSO

  1. The user logs into the IDP’s dashboard, by keying in his/her credentials.
  2. Upon successful authentication the user is presented with a dashboard which has links to the various services the user can access. Something similar to
    okta single sign on
    okta single sign on
  3. Once the user clicks on each of the item in the dashboard, a similar flow starting from step 3 of Service provider initiated SSO.

Structure of a SAML token

<samlp:Response
	xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
	xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685">
	<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
	<samlp:Status>
		<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
	</samlp:Status>
	<saml:Assertion
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="pfxfafb9685-0006-1852-e398-f83adf92403e" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
		<saml:Issuer>http://idp.example.com/metadata.php</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/2000/09/xmldsig#rsa-sha1"/>
				<ds:Reference URI="#pfxfafb9685-0006-1852-e398-f83adf92403e">
					<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/2000/09/xmldsig#sha1"/>
					<ds:DigestValue>lks2jHMzDkbI/bblue0NdP9X1Rw=</ds:DigestValue>
				</ds:Reference>
			</ds:SignedInfo>
			<ds:SignatureValue>J0sD9oGi34vDITax0Oi8SfSlSR1FX9/E4eeMmqAgVy29DuWmMP/NaMmcyXXtgFrHkb9DXC/q0eIcA4DJ3T15eYUJlFBuYQ1rv64JfawX4nMdjmU7Vr9K6Oi2CodvofUjeafoAsPXcHCJl+WMa1L+L6rE3OvxKaGVmdWxYASACKQ=</ds:SignatureValue>
			<ds:KeyInfo>
				<ds:X509Data>
					<ds:X509Certificate>MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lbG9naW4gSW5jMRcwFQYDVQQDDA5zcC5leGFtcGxlLmNvbTAeFw0xNDA3MTcxNDEyNTZaFw0xNTA3MTcxNDEyNTZaMFIxCzAJBgNVBAYTAnVzMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQKDAxPbmVsb2dpbiBJbmMxFzAVBgNVBAMMDnNwLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZx+ON4IUoIWxgukTb1tOiX3bMYzYQiwWPUNMp+Fq82xoNogso2bykZG0yiJm5o8zv/sd6pGouayMgkx/2FSOdc36T0jGbCHuRSbtia0PEzNIRtmViMrt3AeoWBidRXmZsxCNLwgIV6dn2WpuE5Az0bHgpZnQxTKFek0BMKU/d8wIDAQABo1AwTjAdBgNVHQ4EFgQUGHxYqZYyX7cTxKVODVgZwSTdCnwwHwYDVR0jBBgwFoAUGHxYqZYyX7cTxKVODVgZwSTdCnwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQByFOl+hMFICbd3DJfnp2Rgd/dqttsZG/tyhILWvErbio/DEe98mXpowhTkC04ENprOyXi7ZbUqiicF89uAGyt1oqgTUCD1VsLahqIcmrzgumNyTwLGWo17WDAa1/usDhetWAMhgzF/Cnf5ek0nK00m0YZGyc4LzgD0CROMASTWNg==</ds:X509Certificate>
				</ds:X509Data>
			</ds:KeyInfo>
		</ds:Signature>
		<saml:Subject>
			<saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID>
			<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
				<saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685"/>
			</saml:SubjectConfirmation>
		</saml:Subject>
		<saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
			<saml:AudienceRestriction>
				<saml:Audience>http://sp.example.com/demo1/metadata.php</saml:Audience>
			</saml:AudienceRestriction>
		</saml:Conditions>
		<saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
			<saml:AuthnContext>
				<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
			</saml:AuthnContext>
		</saml:AuthnStatement>
		<saml:AttributeStatement>
			<saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
				<saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
			</saml:Attribute>
			<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
				<saml:AttributeValue xsi:type="xs:string">test@example.com</saml:AttributeValue>
			</saml:Attribute>
			<saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
				<saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue>
				<saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue>
			</saml:Attribute>
		</saml:AttributeStatement>
	</saml:Assertion>
</samlp:Response>

As we can see above a SAML token contains the following sections

  1. Issuer - which is the IDP who issued the token.
  2. Issue Instant - the time at the point when the token was generated.
  3. Assertion - Which contains the digital signature of the token(more details later)
  4. Assertion in turn contains

    • Digest Algorithm - SHA1/MD5/SHA512 etc
    • Digest - The digest of the message MD5(samltoken) or SHA1(samltoken) etc
    • Digital Signature - which is the signature generated using the private key of the Identity Provider(this has to be private or else some one can be issuing SAML tokens)
    • The certificate which can be used to verify the signature
  5. The Subject/Service provider’s information like the qualifier(http://foo.bar.orielly.com/metadata.php)
  6. The AuthNStatement which contains the validity time of the SAML token beyond which the Service provider should consider the token to be invalid.
  7. AttributeStatement which contains basic information of the user like

    • Email Address
    • User name
    • Date of birth
    • Role within the firm

Pre requisite steps

Before the Service provider starts providing services to clients it has to have several metadata about the client, so that it can associate users with the respective clients. In order to achieve this following items

  1. Realm discovery mechanism: If the user directly accesses the Service provider’s services, and if the user is not authenticated then the service provider should have a mechanism using which it can redirect to the IDP of the user. There are various ways to solve this, one common way is to prefix the client’s name to the URL of the service provider and ask all of the users of the clients to access the service provider using this URL. For example foo.bar.orielly.com
  2. Client certificate: In order to verify the SAML token issued by the IDP, the service provider has to have the certificate which can be used to verify the signature which was generated using a private key. The IDP will have this Private key + Certificate key pair, using the private key the IDP will sign the tokens and using the certificate the service provider will verify them. Hence there should be a way to transfer/copy this certificate from the IDP to the service provider
  3. Meta data: There will be other meta data information which will be required by the service provider to fulfil the authentication steps, some examples would be: redirect url, idp url etc

Flow Diagram

Service provider initiated SSO
Service provider initiated SSO

Conclusion

With the introduction of single sign on, now the IT administrators have a single place to grant/revoke access. The users need not remember different user names and passwords for different services which they use. The service providers need not worry about the user data getting leaked out.

Kumar D

Kumar D

Software Developer. Tech Enthusiast. Loves coding 💻 and music 🎼.

Read More
Single Sign On with SAML
Share this