SP-Initiated Single Sign On using SAML 2.0–Architecture and a simple implementation

Identity Provider (idP) : Party which authenticates the user
Service Provider(SP/RP) : Party which provide a resource/service to the user. Also called a relying party.

Below are the high level steps and I will expand on them later in this article :-

  1. User tries to access a resource on the SP website
  2. SP saves the requested resource URL, sees there user does not have a session with them. It then sends the user (with a SAMLRequest) back to the idP it trusts to authenticate.
  3. idP checks if the user has a session with them and If not challenges the user to log in.
  4. Upon successful login, idP sends the user to the SP with a SAML assertion.
  5. SP verifies the SAML assertion, creates a session for the user and lets the user access the resource.

[Click on the below image to enlarge]


1. User tries to access a resource on the SP website
This step is simple. User access a link on the SP.
GET http://serviceprovider.com/serviceproviderweb/Folder1/Folder2/Folder3/DeeplyPlacedFile.asp?id=1 HTTP/1.1
Typically each SP website page user accesses directly (e.g. DeeplyPlacedFile.asp) would check If user has an existing session (e.g. has the required valid SP auth cookie), It will let us user stay in the page the SSO flow ends here. If the user does not have an active session next steps (starting from 2) ) below will follow.

Typically, SP website have cookie check in each page via shared lib. In the example below Its an ASP include file which can be used in all the ASP pages within the SP website.

Note the line :-
Response.Redirect “https://federationengine.serviceprovider.com/sp/startSSO.ping?partnerIdpId=https://federationengine.identityprovider.com&TargetResource=”&url
The above line indicates there is an PingFederate idP connection (with the name ‘https://federationengine.identityprovider.com’) on the service provider federation engine.
This will create a AuthNRequest (SAMLRequest) and will port to the SSO URL on the idp side.
Also note that the the requested Url is also tagged along with the TargetResource querystring. This will make sure the idP Connection would create a relaystate token and will map the same to the requested URL. (more details on this later)

Dim protocol
Dim domainName
Dim fileName
Dim queryString
Dim url

protocol = “http”
If lcase(request.ServerVariables(“HTTPS”))<> “off” Then
protocol = “https”
End If

domainName= Request.ServerVariables(“SERVER_NAME”)
fileName= Request.ServerVariables(“SCRIPT_NAME”)
queryString= Request.ServerVariables(“QUERY_STRING”)

url = protocol & “://” & domainName & fileName & “?” & queryString

cookieValue = Request.Cookies(“ServiceProviderAuthCookie”)
if len(cookieValue) < 1  Then

Response.Redirect https://federationengine.serviceprovider.com/sp/startSSO.ping?partnerIdpId=https://federationengine.identityprovider.com&TargetResource=”&url

end if

2. SP asks the idP to authenticate the user
If the SP’s federation server determines there is no active session for the user and user is coming for the first time, the federation server constructs an SAML Authentication request also called “SAMLRequest” and sends the base64 version of it to the idP federation server SSO URL.
It also creates an identifier (as a RelayState), saves along with the originally requested URL as a key-value pair. This is done so that when the idP comes with the same identifier, It can retrieve the originally requested URL and can just redirect the user. This way, there is no need of passing the URL around.

If the authentication request is sent via POST, there are the SAMLRequest and RelayState are sent in hidden fields,
RelayState: FMCbXM9vrgFI0jT5ZvqC4hieR3JVT4

Below is the Xml representation of the SAMLRequest :-
<samlp:AuthnRequest Version=”2.0″
<saml:Issuer xmlns:saml=”urn:oasis:names:tc:SAML:2.0:assertion”>http://www.serviceprovider.com</saml:Issuer>
<samlp:NameIDPolicy AllowCreate=”true” />

Notice the highlighted issuer id. This is the entityid of the service provider. This is needed by the identity provider to determine which party It needs to issue the SAMLResponse to.

3. idP checks if the user has a session with them and If not challenges the user to log in
idP Federation server, upon getting the authentication request, initializes the appropriate connection configuration for the service provider (identified by the SP issuer id sent in the previous step). The configured authentication adapter in teh connection is invoked and user is challenged.

4. idP sends SAML assertion to the SP Federation engine
Upon successful user login, the server issues the SAMLResponse. This SAMLResponse is signed with the idP’s private certificate and other attributes needed for the SP to create the session for the user.
If the authentication request is sent via POST, there are the SAMLRequest and RelayState are sent in hidden fields. Notice, Its the RelayState hidden field has the same value SP passed to the idp in step 2).
SAMLResponse: PHNhbWxwOlJlc3BvbnNlIFZlcnNpb249IjIuMCIgSUQ9IldJcHlvTnVrRkdZQ3Q3b0FuQ1JnOHpFUG9V
RelayState: FMCbXM9vrgFI0jT5ZvqC4hieR3JVT4

XML respresentation of SAMLResponse below :-
Key points here are :-
a) The issuer id “www.identityprovider.com” is the identity provider’s entity id.
b) The SAML is issued to the entity id “www.serviceprovider.com” of the service provider.
c) SAML is posted to the Assertion Consumer Service (ACS) URL https://www.serviceprovider.com/sp/ACS.saml2 of the service provider.
<samlp:Response Version=”2.0″
<saml:Issuer xmlns:saml=”urn:oasis:names:tc:SAML:2.0:assertion”>www.identityprovider.com</saml:Issuer>
<samlp:StatusCode Value=”urn:oasis:names:tc:SAML:2.0:status:Success” />
<saml:Assertion ID=”fciE1SgZ2WX-duiqbwBiuvZj9XT”
<ds:Signature xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;
<saml:NameID Format=”urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified”>48DEDA35890E4746A134920E70844E6A</saml:NameID>
<saml:SubjectConfirmation Method=”urn:oasis:names:tc:SAML:2.0:cm:bearer”>
<saml:SubjectConfirmationData Recipient=”https://www.serviceprovider.com/sp/ACS.saml2&#8243;
<saml:Conditions NotBefore=”2016-03-04T01:01:17.050Z”
<saml:AuthnStatement SessionIndex=”fciE1SgZ2WX-duiqbwBiuvZj9XT”

5. SP federation engine validates the SAML assertion and redirects to SP portal
SP federation engine verifies the signature on the SAML with the publice cert (previously sent offline) and if the verification is successful, creates the session (e.g. via a cookie).
The RelayState token also comes as part of the POST request. It also pulls up the originally requested URL mapped with that token and redirects the user to the the URL.

, ,

  1. #1 by Dinesh on January 4, 2018 - 8:48 am

    Hi Ashish,

    Good Article. Do you have sample .net solution to achieve SP_initiated SSO or any video tutorial? I have ADFS as IDP and Ping Federate as SP. I am looking in particular for what needs to be done from application point of view(code from service provider’s asp site page). I have configured on ping federate with SP Initiated SSO and SSO service URL’s. From above article I had one question, what would be service provider auth cookie? I have configured Transport Mode as Form POST in ping federate SP Adapter and gave token name as “opentoken” – is this one you are referring in above article.

    Any help is appreciated!!

  2. #2 by Ashish Gupta on January 5, 2018 - 11:37 pm

    Thank you Dinesh.
    By Auth cookie, I meant the cookie which the SP creates after successful idP authentication and SP SAMLResponse validation. You many also term that as a SP “session” cookie.

    Let us consider the below 2 scenario which probably make thing more clear.

    The flow when the user does not have the SP auth cookie (first time):
    User goes to SP deep link > SP checks for the Auth/Session cookie > There is no cookie > SP sends a SAML request to iDP > IdP prompts the user for authentication > After successful auth, SAML response is sent to SP > SP validates the digital signature on the SAML response > Creates the auth/session cookie.

    After the above, if the user visits the SP deep link again :
    User goes to SP deep link > SP checks for the Auth/Session cookie > There is one and It is valid > No need to send a SAML request idP > user remains in SP website.

    The openntoken could be created by the PingFederate but the SP application behind it must validate it. There is a .NET based integration kit. Link below.


    Let me know If that answers your question.

  3. #3 by Akhil on January 20, 2019 - 2:04 pm

    Hi Ashish,
    It was a great explanation. There is one thing i’m not able to figure out. So at IdP, user authentication is done by querying a database and SP gets to know that the user is a valid one by verifying the certificate on the response by the IdP right? Please correct me if i am wrong.
    Thanks in advance.

    • #4 by Ashish Gupta on February 17, 2019 - 7:17 pm

      hello Akhil. Thank you. Your above description is correct.

Leave a Reply to Ashish Gupta Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Random Thoughts

The World as I see it

Simple Programmer

Making The Complex Simple

Ionic Solutions

Random thoughts on software construction, design patterns and optimization.

Long (Way) Off

A tragic's view from the cricket hinterlands

%d bloggers like this: