This series of posts and associated code is aimed at removing the mystery of SAML implementation and highlight what is happening in the common SAML workflows.
What is SAML?
- Security Assertion Markup Language (better known as its acronym, SAML) is a protocol for authenticating to web applications.
But why do we need such a protocol?
- Imagine you build a web application which you would want to sell to Enterprises.
- Now, as the users (say employee of this company) access your application, you would like them to authenticate against the company login system.
🔥 Of course the other choice is that users register with your application and then your app maintains their credentials, separate from company login system. This is poor choice. Why? Its poor user experience since users need to register again on your app and its poor security since they need to maintain multiple set of credentials.
- After user completes authentication, the company login system must be able to inform your application about the user in a secure way.
- That’s where SAML comes in.
At a high level this is how the flow looks like —
Sequence Diagram explained
The Participants
Identity Provider (IDP)
The service that performs the authentication; checking usernames and passwords, invoking Multi-Factor Authentication etc. So the company login system is the Identity Provider in this case.
The means by which Identity provider authenticates the user is not mandated by SAML The most common is userid/password based authentication but its entirely up to the provider
Service Provider (SP)
Your application is the Service Provider, literally, it is providing a service to the end user.
The Flow
- Step 1–2 : When the user tries to access the application,
SP
asks theIDP
to authenticate the user. The “ask” is expressed asSAML AuthRequest
. - Step 3–5:
IDP
will then interact with User to authenticate the User. - Step 6:
IDP
responds by sending details of the authenticated user. This is expressed asSAML Assertion
. - Step 7 : A
SAML Assertion
is a message asserting the user’s identity and other information about user. The message is almost always “signed” byIDP
as proof of integrity.SP
verifies the assertion and then extracts the User information . - The SAML flow is complete and
SP
can now allow the user to access the application
📓 Both the
SAML AuthnRequest
andAssertion
are encoded XML documents
Lets see these in action
Here is a video of the service provider running on my Mac using the code from GitHub repo.
Try it yourself
Head over to https://github.com/monmohan/samltools and follow the instructions in README.md
.
After you are all set and start the SP server, visit the SP home page in the Browser. You should see this -
- Click the
Show SAML AuthnRequest
button
You will see the request XML like below —
Here is an explanation of the relevant fields —
Alright, so we are all set to send this request over to IDP.
Go ahead and click the nice blue button named SEND REQUEST.
Following things would happen, if all is configured right -
- The URL of the page will change to something like
https://dev-ejtl988w.auth0.com/samlp/lqrbWWMYc25UrCiYA5Pt06U625c4K6DO?SAMLRequest=fJAxa%2FNADIb3......
- The first part of the URL is called as Single SignOn URL and this is the IDP URL where you are sending the user, BUT, along with an additional query parameter called
SAMLRequest
, the value of which is an encoded representation of the XML we saw earlier. - Once the request reaches the IDP, it will challenge the user to authenticate (assuming there is no existing session in the Browser). For example, the default IDP (Auth0) configured in the repo, brings the screen as below
📓 If you are using a different IDP than the default configured in the sample, then your URL would look differently but the concept remains same. It will be the SSO URL which IDP will provide to the SP.
- Once the user has authenticated, you would see the page URL changed to http://sp.samltools.com:4567/assertion
- What happened here is that IDP (Auth0), verified the user credentials, and then generated a SAML Assertion. Now, IDP needs to send this assertion to the SP so that SP can identify the user.
- So the SP provides a URL, also known as ACS (Assertion Consumer Service) URL , where this assertion needs to be sent. This URL needs to be pre-configured in the IDP.
- IDP (depending on the
Issuer
of the Request) can now send the assertion to the corresponding ACS URL We configuredhttp://sp.samltools.com:4567/assertion
as the ACS URL and hence the assertion is posted to this URL after the User authentication completes.
SAML Assertion
Finally you would see the actual assertion on the page.
This is because in the current sample code, we just show the assertion as received in the HTTP POST request from the IDP.
You would see something like below —
The full sample XML can be reviewed here : https://github.com/monmohan/samltools/blob/main/samples/saml-assertion-example.xml
Key Elements and Attributes
The notable things in the Assertion XML are :
<saml:Subject>
element which identified the subject of this assertion; the User.- Multiple
<saml:Attribute>
elements which identify different User attributes like Name, Email, whether the email is verified or not, and so on. Example of one such entry is this :
- The exact name of such attributes, and what attributes are returned as part of assertion is a configured at the IDP for the SP.
- The
Signature
element which contains , as the name suggests , the signature of the assertion. In conjunction with the IDP certificate, it helps the SP verify that the assertion is indeed from the IDP it trusts.
Hopefully this article has given you a good overview of SAML protocol and a good understanding of a Service Provider. In the next articles, we will see more of the IDP
side of story and further details of Assertion. This will help us understand the SP
← → IDP
link better, without the need of a provider like Auth0.
That’s it folks !