SAML 2.0 IdP-Initiated Sign-On with RelayState in ADFS 2.0

Ýet another riveting title Smile Dispensing with WS-Federation, we’ll move onto looking at SAML 2.0 integration with AD FS, in particular IdP-Initiated sign-on. In the last few posts we’ve looked at how AD FS 2.0 admins can manipulate the use of the whr function to assist in the realm discovery process as part of sign-in to AD FS using WS-Federation. With AD FS 2.0 and SAML 2.0, a long-awaited feature has been support for SAML 2.0 RelayState. With Rollup 2, the AD FS team have come up with the goods. Like whr on the WS-Federation side, the use of RelayState allows us to support IdP-Initiated login from a SAML 2.0 identity provider (IdP).

Before we look at some examples, here’s a few useful tools to aid building and debugging the use of RelayState.

1. The excellent SAML Tracer plugin for Firefox (

2. A relay state generator for AD FS 2.0 to aid us in building the necessary call-back to AD FS. (

3. A URL Encoder/Decoder to validate the syntax used for constructing the Relaystate query string. I used this one..

To get started, there’s a nice article on the Directory Services blog at Microsoft, as a backgrounder to understanding what’s going on via Rollup 2 and RelayState.

Let’s have a look at how these scenarios may pan out. Putting my rudimentary skills in Visio 2013 to the test, here are three examples:


EXAMPLE 1: Remote SAML 2.0 Identity Provider

In the above example, our user needs to connect, via the Internet, to a remote web application that is configured as a SAML 2.0 Service Provider. This service provider is engaged in a federation trust with AD FS. AD FS as a Relying Party Security Token Service (RP-STS) has the SAML 2.0 Identity Provider (IdP), in the home realm of the user, configured as a claims provider (CP).


EXAMPLE 2 : Remote SAML 2.0 Identity Provider and Service Provider

In the above scenario, both the service provider (SP) and the identity provider (IdP) are remote to the organization. This could be a cloud / SaaS application that the RP-STS organization provides access to to both its users and the remote identity provider organization.


EXAMPLE 3 : Remote SAML 2.0 Service Provider

In the above example, the Identity Provider (IdP) and AD FS are part of the same organization.  The IdP could be an Access Management platform such as OpenAM, a remote access gateway such as a Juniper SA, or an Extranet ADFS instance with the AD FS RP-STS acting as a broker.

Access Scenario

Let’s look at some of the pre-requisites on the AD FS side:

1. Install AD FS 2.0 Rollup 2 on all instances where AD FS is involved: proxies, farm members and also third-party organizations if AD FS is installed there.

2. Add the following change to <microsoft.identityServer.web> section of the IIS web.config of all participating AD FS instances, under the /adfs/ls path.

   <useRelayStateForIdpInitiatedSignOn enabled=”true” />

In this example we’ll evaluate ADFS in a SAML 2.0 Identity Provider (IdP) role within a third party Organization, called Fie, and also as a Relying Party Security Token Service (RP-STS) within the resource organization (Foo).  Fie Users may click on a hyperlink or a bookmark that kicks off the logon process with their IdP, and through the use of RelayState, via the parameterized Relying Party Identifiers provided to the IdP and RP-STS ADFS instances, the user is sent to the service provider application.

For our web application and SAML 2.0 SP, I’m going to use cloud provider OneLogin. This will act as an application portal. Once logged on via the IdP, the user is sent to the OneLogin portal thru the RP-STS of Foo. Referring to the diagrams above, this access scenario probably best fits Figure 2. Since the web application belongs to Foo, we’re using an indirect trust involving the Foo ADFS instance as an RP-STS. Fie is a claims provider (CP) to the Foo organization ADFS and the web application is a SAML 2.0 Service Provider (SP) that trusts the ADFS instance as an Identity Provider (IdP).

Here are the service endpoints and relying party identifiers that we need to use to build the appropriate link.

Using the new notation provided in Rollup 2, two relying party identifiers (RPID) are required in order for the relay to the web application to work correctly. The RPID in ADFS terms is the identifier. For a SAML 2.0 SP, this is the Entity ID of the web application. In some scenarios the entity ID may not be sufficient and additional parameters required. Refer to the Microsoft article mentioned earlier on how this may be further encapsulated into the RelayState. I’ve included the URL encoded and decoded syntax below to give you an idea the syntax we’re forming.

Here’s the URL Decoded link, broken into three parts:

  1. &RelayState=RPID=
  2. &RelayState=RPID=

Part 1 is the URL of the Identity Provider, Part 2 the query string and RelayState for the RP-STS, and Part 3 state for the SAML 2.0 SP.

Users logon on at Fie IdP, either through the AD FS proxy using forms-logon, when connecting externally or with their Windows logon ID thru the ADFS farm.  Once we’ve encoded the link, it looks like this:

And we hit the OneLogin portal:


I began the post with a smiley, so I’ll end with one.. nice feature Smile..

3 thoughts on “SAML 2.0 IdP-Initiated Sign-On with RelayState in ADFS 2.0

  1. Thanks for excellent article. How can we achieve same functionality using ADFS 3.0? We need to use IDP-Initiated SSO using ADFS 3.0 for a 3rd party application.


    1. Hi Shubham,

      Are you having problems configuring RelayState in AD FS 2012 R2. This moves into section of the Microsoft.IdentityServer.Servicehost.exe.config file under C:\Windows\ADFS

  2. Hi, this post was the inspiration for a deployment I just released to production 🙂

    It all started with a customer who has some sort of login page on PHP and a set of shell scripts that work as an Apache web server external provider of basic authentication. The outcome of a successful authentication is an Apache server variable whose value is the connected user. It works for their on-premises applications, as they are published through these Apaches, but for Outlook webmail… well, they used to keep in memory user and password which populated and submitted a login form to Office365. The source for that form has to be re-copied from time to time

    The users are kept in an authoritative LDAP which syncs to an Active Directory and the on-premises AD FS, and in turn it syncs to Azure AD.

    So, first step was to deploy a SimpleSAMLphp (SSP) IdP in the role of the SAML IdP described here. This IdP is protected with that basic authentication so that a custom SSP authentication module can read the user identity from the Apache variable and read the user attributes from the LDAP and issue claims. One of those claims is the full DOMAIN\user identified as AD FS expects it.

    Then comes AD FS 2.0 as the RP-STS. The SSP SAML IdP sees a Relying party, AD FS sees the SAML IdP a claims provider trust. As a claims provider trust, an AD FS custom claims rule passes the windows account name with the only change od setting “AD AUTHORITY” as the issuer.

    This windows account name is used by the three magic claims rules of the AD FS Office 365 relying party. The first takes the account name, regexp-splits the user and takes it as a parameter for an AD search that brings the UPN and the very necessary ImmutableID which is the basic claims that Office365 expects. ImmutableID, obtained from AD ObjectGUID, is the basis of the DirSync between on premises AD FS and the cloud. The second rule just transforms the ImmutableID into a persistent NameID, and the thirs takes the domain part of the UPN as a mail address to get the value of the IssuerId in the SAML 1.0 assertion that AD FS sends to Office 365. This SAML 1.0 is the secure token in an STS statement sent as a WS-Federation message.

    So, as long as the user has already logged in with the legacy login page (which they want to keep), the user can now access an URL which is a SimpleSAMLphp IdP initiated sign on pointing to the entityId of AD FS.

    We could add a RelayState in order to send the user to the urn:microsoft:online (Office 365) relying party, but AD FS although properly configured to relay fails to do so towards Office.

    So we had to add to AD FS a service provider which is just a minimal second installation of SimpleSAMLphp (just to generate SP metadata) and a PHP page that when reached redirects to a SmartLink that takes the user to Office365 and Outlook. That SmartLink is an AD FS URL that does the proper redirect, and is WS-Federation based. The SAML SP that redirects back to AD FS does nothing else, not even testing the SAML assertion from AD FS.

    This requires adding to the original URL for SimpleSAMLphp a RelayState which contains URL encoded (twice) data for AD FS: the RPID (relying party identifier) parameter of the SAML SP that redirects back to the SmartLink, and a nested RelayState parameter with the actual URL of the SP.

    It worked, thanks for the inspiration. I had previous experience in mixing several IdP (SSP, Shibboleth, AD FS) and even expanded Shibboleth a couple of times for custom N-factor authentication, but this WS-Federation last leg has needed some figuring out! 🙂

Leave a Reply

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

You are commenting using your 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