Implementing Single Sign-On (SSO) using SAML for authentication in web applications | Web SAML SSO Authentication

Requirement:

You have a web based solution/application that your customer utilizes.  The current use case is that users from your customer company registers with your web application for authentication and access to the application. This requires your web application to support a complete User Management Module (that supports user registration, authentication, Password reset and recovery for forgotten passwords, enforcing password policy of your customer in your application, etc.,). 

Considering the support hours and user time in password management and logon issues, your customer would like to have their users automatically authenticated against your web application.

Solution is:

Web SSO which Implements Single Sign-On (SSO) using SAML for authentication in web applications

The Web SAML SSO Authentication is about how to support user logon to a web application/resource without explicitly providing the username and password credentials instead the browser automatically contacts their Identity Management Provider (IdP like ADFS/ or others) and gets a authorization ticket which can be used for authenticating against all web applications that are registered as Relying Parties with the backend Identity Management system.  This way, on Web via browser, user authenticates once with their IdP, and uses the SAML token to automatically authenticate against any other registered web applications/services.  

SAML (Security Assertion Markup Language) is the technology that providers protocols/methods for Web SSO.  Currently in V2.0 SAML supports two general message flows to support the overall process.  They are :

  • SP-initiated SSO:
  • SP-initiated SSO using a Redirect Binding for the SP-to-IdP <AuthnRequest> message and a POST Binding for the IdP-to-SP <Response> message
  • SP-initiated SSO using a POST Binding for the <AuthnRequest> message and an Artifact Binding for the <Response> message
  • IDP-initiated SSO:
  • IDP-initiated SSO using a POST Binding for the IdP-to-SP <Response> message; no SP-to-IdP <AuthnRequest> message is involved.

Here is the detailed explanation of the flow of SP-initiated SSO using a Redirect Binding: This first example describes an SP-initiated SSO exchange. In such an exchange, the user attempts to access a resource on the SP, sp.example.com. However they do not have a current logon session on this site and their federated identity is managed by their IdP, idp.example.org. They are sent to the IdP to log on and the IdP provides a SAML web SSO assertion for the user’s federated identity back to the SP.  For this specific use case, the HTTP Redirect Binding is used to deliver the SAML <AuthnRequest> message to the IdP and the HTTP POST Binding is used to return the SAML <Response> message containing the assertion to the SP. Figure 12 illustrates the message flow.

SP-Initiated SSO with Redirect and POST Bindings

The processing is as follows:

  1. The user attempts to access a resource on sp.example.com. The user does not have a valid logon session (i.e. security context) on this site. The SP saves the requested resource URL in local state information that can be saved across the web SSO exchange.
  2. The SP sends an HTTP redirect response to the browser (HTTP status 302 or 303). The Location
    HTTP header contains the destination URI of the Sign-On Service at the identity provider together with an message encoded as a URL query variable named SAMLRequest.

[code language=”xml”]
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="identifier_1"
Version="2.0"
IssueInstant="2004-12-05T09:21:59Z"
AssertionConsumerServiceIndex="1">
<saml:Issuer><a href="https://sp.example.com/SAML2">https://sp.example.com/SAML2</a><!–<span class="hiddenSpellError" pre=""–>saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="true"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
<!–<span class="hiddenSpellError" pre=""–>samlp:AuthnRequest>
[/code]

The query string is encoded using the DEFLATE encoding. The browser processes the redirect response and issues an HTTP GET request to the IdP’s Single Sign-On Service with the
SAMLRequest query parameter. The local state information (or a reference to it) is also included in the HTTP response encoded in a RelayState query string parameter.

https://idp.example.org/SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token

  1. The Single Sign-On Service determines whether the user has an existing logon security context at the identity provider that meets the default or requested (in the ) authentication policy requirements. If not, the IdP interacts with the browser to challenge the user to provide valid credentials.
  2. The user provides valid credentials and a local logon security context is created for the user at the IdP.
  3. The IdP Single Sign-On Service builds a SAML assertion representing the user’s logon security context. Since a POST binding is going to be used, the assertion is digitally signed and then placed within a SAML message. The message is then placed within an HTML FORM as a hidden form control named SAMLResponse. If the IdP received a RelayState value from the SP, it must return it unmodified to the SP in a hidden form control named RelayState. The Single Sign-On Service sends the HTML form back to the browser in the HTTP response. For ease of use purposes, the HTML FORM typically will be accompanied by script code that will automatically post the form to the destination site.

[code language=”xml”]
<form method="post" action="https://sp.example.com/SAML2/SSO/POST" …>
<input type="hidden" name="SAMLResponse" value="response" />
<input type="hidden" name="RelayState" value="token" />

<input type="submit" value="Submit" />
</form>
[/code]

The value of the SAMLResponse parameter is the base64 encoding of the following element:

[code language=”xml”]
<samlp:Response
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="identifier_2"
InResponseTo="identifier_1"
Version="2.0"
IssueInstant="2004-12-05T09:22:05Z"
Destination="<a href="https://sp.example.com/SAML2/SSO/POST&quot;">https://sp.example.com/SAML2/SSO/POST"</a>>
<saml:Issuer><a href="https://idp.example.org/SAML2">https://idp.example.org/SAML2</a><!–<span class="hiddenSpellError" pre=""–>saml:Issuer>
<samlp:Status>
<samlp:StatusCode
Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="identifier_3"
Version="2.0"
IssueInstant="2004-12-05T09:22:05Z">
<saml:Issuer><a href="https://idp.example.org/SAML2">https://idp.example.org/SAML2</a><!–<span class="hiddenSpellError" pre=""–>saml:Issuer>
<!– a POSTed assertion MUST be signed –>
<ds:Signature
xmlns:ds="<a href="http://www.w3.org/2000/09/xmldsig#&quot;">http://www.w3.org/2000/09/xmldsig#"</a>>…
<saml:Subject>
<saml:NameID
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
3f7b3dcf-1674-4ecd-92c8-1544f346baf8
<!–<span class="hiddenSpellError" pre=""–>saml:NameID>
<saml:SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData
InResponseTo="identifier_1"
Recipient="<a href="https://sp.example.com/SAML2/SSO/POST&quot;">https://sp.example.com/SAML2/SSO/POST"</a>
NotOnOrAfter="2004-12-05T09:27:05Z"/>
<!–<span class="hiddenSpellError" pre=""–>saml:SubjectConfirmation>
<!–<span class="hiddenSpellError" pre=""–>saml:Subject>
<saml:Conditions
NotBefore="2004-12-05T09:17:05Z"
NotOnOrAfter="2004-12-05T09:27:05Z">
<saml:AudienceRestriction>
<saml:Audience><a href="https://sp.example.com/SAML2">https://sp.example.com/SAML2</a><!–<span class="hiddenSpellError" pre=""–>saml:Audience>
<!–<span class="hiddenSpellError" pre=""–>saml:AudienceRestriction>
<!–<span class="hiddenSpellError" pre=""–>saml:Conditions>
<saml:AuthnStatement
AuthnInstant="2004-12-05T09:22:00Z"
SessionIndex="identifier_3">
<saml:AuthnContext>
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
<!–<span class="hiddenSpellError" pre=""–>saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
[/code]

  1. The browser, due either to a user action or execution of an “auto-submit” script, issues an HTTP POST request to send the form to the SP’s Assertion Consumer Service.

[code language=”xml”]
POST /SAML2/SSO/POST HTTP/1.1
Host: sp.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: nnn
&nbsp;
SAMLResponse=response&RelayState=token
[/code]

where the values of the SAMLResponse and RelayState parameters are taken from the HTML form of Step 5. The service provider’s Assertion Consumer Service obtains the message from the HTML FORM for processing. The digital signature on the SAML assertion must first be validated and then the assertion contents are processed in order to create a local logon security context for the user at the SP. Once this completes, the SP retrieves the local state information indicated by the RelayState data to recall the originally-requested resource URL. It then sends an HTTP redirect response to the browser directing it to access the originally requested resource (not shown).

  1. An access check is made to establish whether the user has the correct authorization to access the resource. If the access check passes, the resource is then returned to the browser.

References:

Leave a Reply

Your email address will not be published. Required fields are marked *