Supporting Identity Provider Initiated RelayState

Updated: May 10, 2012

Applies To: Active Directory Federation Services (AD FS) 2.0

Some organizations may want to support identity provider-initiated (IDP initiated) web-based single sign-on (SSO) as described by OASIS in the Security Assertion Markup Language (SAML) specification. For more information, see the OASIS Web site.

Active Directory Federation Services (AD FS) 2.0 provides a way for organizations to enable additional support for streamlined IDP initiated SSO using the Update Rollup 2 for AD FS 2.0 package. Once configured, AD FS 2.0 will have the ability to consume RelayState in order to redirect the user to the relying party application.

For more information about the fixes, new capabilities, download location and installation instructions associated with this package, see Description of Update Rollup 2 for Active Directory Federation Services (AD FS) 2.0 on the Microsoft Support site.

What is RelayState?

RelayState is a parameter used by some SAML protocol implementations to identify the specific resource at the resource provider in an IDP initiated single sign on scenario. The value of the RelayState parameter as interpreted by AD FS in IDP initiated scenarios, is divided into two components:

Component Description

RPID

This required value is the relying party identifier (RPID). It is consumed by the STS that receives the RelayState along with a SAMLResponse. It identifies the relying party trust that the STS will select automatically, eliminating the need for the user to select a relying party trust interactively.

Nested RelayState or wctx

The second (optional) component of the RelayState value is intended to be passed to the relying party as RelayState.

AD FS 2.0 default behavior

If Update Rollup 2 is not used, the default behavior for AD FS 2.0 is to ignore RelayState and, when it receives an identity provider-Initiated SAML Response, to send a subsequent SAML authentication request back to the identity provider. As a result, not only is the scenario effectively transitioned from an identity provider-Initiated to a relying party initiated single sign on, but the user must interactively choose a relying party rather than being forwarded seamlessly to the correct resource. 

Additionally, AD FS 2.0 will lose the context of the initial response when sending the subsequent authentication request. If any claims were sent with the initial SAML Response, they will be lost because a specific claim included in the initial response cannot be reconstructed by the identity provider without some context from the original response.

Behavior when Update Rollup 2 for AD FS 2.0 is used

When Update Rollup 2 for AD FS 2.0 is used, AD FS 2.0 servers will consume the unsolicited SAML Response directly rather than sending a subsequent SAML authentication request back to the identity provider. ADFS 2.0 servers will also consume the RelayState value and use it to redirect the browser to the target application.

In summary, the following IDP initiated flows are supported when AD FS 2.0 servers are running the Update Rollup 2.0 for AD FS 2.0 hotfix:

  • Identity provider security token server (STS) -> relying party STS (configured as a SAML-P endpoint) -> SAML relying party App

  • Identity provider STS -> relying party STS (configured as a SAML-P endpoint) -> WIF (WS-Fed) relying party App

  • Identity provider STS -> SAML relying party App

However, the following initiated flow is not supported:

  • Identity provider STS -> WIF (WS-Fed) relying party App

Example of IDP initiated flow

The following example demonstrates how a customer might format the request URL at the IDP initiated portal site and how the value would propagate from the identity provider to the relying party STS and on to the relying party.

At the identity provider STS

When the identity provider STS is ADFS 2.0

The portal site at the identity provider contains a link (or set of links) that users will click to initiate the IDP initiated flow. This link will be appended with an encoded RelayState value containing two main components:

Component Description

RPID

This value is the relying party identifier. It is consumed by the immediate STS (the identity provider STS in this case). It identifies the relying party trust that the identity provider STS will select automatically, eliminating the need for the user to select an relying party trust interactively.

Nested RelayState

This portion of the RelayState value is intended to be passed to the relying party as RelayState.

An example link on the identity provider portal would look like the following:

https://idp/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID%3Dhttps%253A%252F%252Ffedp.com%26RelayState%3DRPID%253Dhttps%25253A%25252F%25252Frelyingpartyapp%2526wctx%253Dappid%25253D45%252526foo%25253Dbar

The URL decoded value of the RelayState above is:

RPID=https%3A%2F%2Ffedp.com&RelayState=RPID%3Dhttps%253A%252F%252Frelyingpartyapp%26wctx%3Dappid%253D45%2526foo%253Dbar

The value of the RPID portion is:

https%3A%2F%2Ffedp.com

The value of the RelayState portion is:

RPID%3Dhttps%253A%252F%252Frelyingpartyapp%26wctx%3Dappid%253D45%2526foo%253Dbar

When the identity provider STS is a third party SAML-P STS

A third party SAML 2.0 identity provider STS would simply need to be configured to send the same output as the ADFS identity provider STS discussed above:

SAMLResponse={base64andURLencodedSAMLResponse}&RelayState= RPID%3Dhttps%253A%252F%252Frelyingpartyapp%26wctx%3Dappid%253D45%2526foo%253Dbar

At the relying party STS

As shown above, the request that goes to the relying party STS (https://fedp.com) will contain parameters (either query string or form body) like the following:

SAMLResponse={base64andURLencodedSAMLResponse}&RelayState=RPID%3Dhttps%253A%252F%252Frelyingpartyapp%26wctx%3Dappid%253D45%2526foo%253Dbar

For the above request, the URL decoded value of the RelayState is:

RPID=https%3A%2F%2Frelyingpartyapp&wctx=appid%3D45%26foo%3Dbar

The value of the RPID portion is:

https%3A%2F%2Frelyingpartyapp

Note that, rather than a nested RelayState, we have a nested wctx intended for the WS-Federation relying party. The value of the nested wctx portion is:

appid%3D45%26foo%3Dbar

The relying party STS thus knows the relying party identifier to which the response should be posted, as well as the nested wctx value that needs to be forwarded to relying party. In this example, the relying party is the one identified by https%3A%2F%2Frelyingpartyapp (decoded to https://relyingpartyapp), and the wctx information is ‘appid%3D45%26foo%3Dbar’ (which, when decoded downstream, will equal ‘appid=45&foo=bar’).

To summarize, the format for RelayState at the relying party STS consists of two components:

Component Description

RPID

Consumed by the relying party STS, contains the identifier of the relying party to which to send the response, value ‘https://relyingpartyapp’

Nested RelayState or wctx parameter, depending upon the relying party’s configured protocol support

Contains relying party specific information to be passed along to the relying party, value is URL encoded [‘appid=45&foo=bar’]

At the relying party (https://relyingpartyapp)

The relying party, if it is a WS-Federation protocol endpoint, would finally receive a POST to https://relyingpartyapp containing a WS-Federation response containing a form control wctx= appid%3D45%26foo%3Dbar

The URL decoded value of the nested wctx is:

appid=45&foo=bar

The relying party expects to get information about the specific relying party app in the format “appid=X”, for e.g. “appid=45”

The design allows for sending this application-specific information as a nested wctx (for WS-Federation applications), or as a nested RelayState (for SAMLP applications).

The additional parameter “foo=bar” shown above was included to illustrate how other parameters could be passed along with appid=45.

Building the URL - SAML Protocol Example

This scenario consists of a SAML-P relying party application, a relying party STS, and an identity provider STS:

  • The SAML-P application is located at URL https://samlrp

  • The SAML-P application is configured as a relying party on the relying party STS. Its relying party identifier (RPID) is uri:samlrp

  • The SAML-P application requires one input parameter, “appid” in the POST body

The URL required at the identity provider’s portal can be constructed using the following steps:

  1. URL encode the relying party ID (RPID) of the SAML-P application (uri:samlrp):

    RPID=URLencoded[uri:samlrp]
    
    RPID=uri%3Asamlrp
    
  2. URL encode any state that should be sent to the SAML-P application as RelayState:

    RelayState=URLencoded[appid=47]
    
    RelayState=appid%3D47
    
  3. Create the complete RelayState value that should be sent to the relying party STS by combining the “RPID” and “RelayState” components above with an “&”, then URL encode the result:

    RelayState=URLencoded[RPID=uri%3Asamlrp&RelayState=appid%3D47]
    
    RelayState=RPID%3Duri%253Asamlrp%26RelayState%3Dappid%253D47
    

    This is the RelayState value that should be sent from the identity provider STS to the relying party STS, in order to (1) auto-select the relying party application identified by “uri:samlrp” and thus avoid interactive relying party selection by the user; and (2) send along the value “appid=47” within the POST body to the SAML-P application.

  4. Determine the RPID by which the relying party STS is known to the identity provider STS. This can sometimes be a url. In this example, the RPID is https://fs.contoso.com/adfs/services/trust. As we did in step 1 above, we will initially URL encode the RPID value:

    RPID=URLencoded[https://fs.contoso.com/adfs/services/trust]
    
    RPID=http%3A%2F%2Ffs.contoso.com%2Fadfs%2Fservices%2Ftrust
    
  5. Similar to step 2 above, URL encode any state that should be sent to the relying party STS as RelayState. This value was determined in step 3:

    RelayState=RPID%3Duri%253Asamlrp%26RelayState%3Dappid%253D47
    

    Note: the URL encoding was already done in step 3 and is required to avoid browsers interpreting the & sign.

  6. Similar to step 3 above, we will combine the RPID from step 4 with the state from step 5 using the & sign, then URL encode the result.

    RelayState=encoded[RPID=http%3A%2F%2Ffs.contoso.com%2Fadfs%2Fservices%2Ftrust&RelayState=RPID%3Duri%253Asamlrp%26RelayState%3Dappid%253D47]
    
    RelayState=RPID%3Dhttp%253A%252F%252Ffs.contoso.com%252Fadfs%252Fservices%252Ftrust%26RelayState%3DRPID%253Duri%25253Asamlrp%2526RelayState%253Dappid%25253D47
    

    This is the RelayState value that should be sent to the identity provider STS, in order to (1) auto-select the relying party STS and thus avoid interactive relying party selection by the user; and (2) send along the correct RelayState value to the relying party STS so that it can then select automatically the SAML-P application and send the appid.

  7. Construct the entire URL by sending the RelayState value above to the identity provider STS (For example, https://idp.fabrikam.com/adfs/ls/):

    https://idp.fabrikam.com/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID%3Dhttp%253A%252F%252Ffs.contoso.com%252Fadfs%252Fservices%252Ftrust%26RelayState%3DRPID%253Duri%25253Asamlrp%2526RelayState%253Dappid%25253D47
    

Result

Upon browsing to the URL in step 7 above, the user should see the following:

  1. Depending on authentication type configured at identity provider STS, an authentication prompt at the identity provider STS (only if previous authentication has not occurred).

  2. The browser will redirect and ultimately land at https://samlrp without any further user interaction.

Building the URL - WS Federation Example

This scenario consists of a WS-Federation relying party that is a WIF application, as well as a relying party STS and an identity provider STS:

  • The WS-Federation application is located at url https://wifapp

  • The WS-Federation application is configured as a relying party on the relying party STS. Its relying party identifier (RPID) is also https://wifapp

  • The WS-Federation application requires one input parameter, called “appid”, in the POST body

The URL required at the identity provider’s portal can be constructed using the following steps:

  1. URL encode the RPID of the WS-Federation application (https://wifapp):

    RPID=URLencoded[https://wifapp]
    
    RPID=https%3A%2F%2Fwifapp
    
  2. URL encode any state that should be sent to the WS-Federation application. (Note: It will be sent as wctx, not as RelayState):

    wctx=URLencoded[appid=47]
    
    wctx=appid%3D47
    
  3. Create the complete RelayState value that should be sent to the relying party STS (it is sent as RelayState, not as wctx, because the relying party STS is configured as a SAML-P relying party on the identity provider STS). Combine the “RPID” and “wctx” components above with an “&”, then URL encode the result:

    RelayState=URLencoded[RPID=https%3A%2F%2Fwifapp&wctx=appid%3D47]
    
    RelayState=RPID%3Dhttps%253A%252F%252Fwifapp%26wctx%3Dappid%253D47
    

    This is the RelayState value that should be sent from the identity provider STS to the relying party STS, in order to (1) auto-select the relying party (WIF) application identified by “https://wifapp” and thus avoid interactive relying party selection by the user; and (2) send along the value “appid=47” as a wctx parameter within the POST body to the WS-Federation application.

  4. Determine the RPID by which the relying party STS is known to the identity provider STS. In this example, the RPID is https://fs.contoso.com/adfs/services/trust. As we did in step 1 above, we will initially URL encode the RPID value:

    RPID=URLencoded[https://fs.contoso.com/adfs/services/trust]
    
    RPID=http%3A%2F%2Ffs.contoso.com%2Fadfs%2Fservices%2Ftrust
    
  5. Similar to step 2 above, we will URL encode any state that should be sent to the relying party STS (as noted above, this time it is sent as RelayState and not wctx). We have already determined this value in step 3 above:

    RelayState=RPID%3Dhttps%253A%252F%252Fwifapp%26wctx%3Dappid%253D47
    

    Note: the URL encoding was already done in step 3 and is required to avoid browsers interpreting the & sign.

  6. Similar to step 3 above, we will combine the RPID from step 4 with the state from step 5 using an & sign, then URL encode the result.

    RelayState=encoded[RPID=http%3A%2F%2Ffs.contoso.com%2Fadfs%2Fservices%2Ftrust&RelayState=RPID%3Dhttps%253A%252F%252Fwifapp%26wctx%3Dappid%253D47]
    
    RelayState=RPID%3Dhttp%253A%252F%252Ffs.contoso.com%252Fadfs%252Fservices%252Ftrust%26RelayState%3DRPID%253Dhttps%25253A%25252F%25252Fwifapp%2526wctx%253Dappid%25253D47
    

    This is the RelayState value that should be sent to the identity provider STS, in order to (1) auto-select the relying party STS and thus avoid interactive relying party selection by the user; and (2) send along the correct RelayState value to the relying party STS so that it can then select automatically the WS-Federation application and send the appid as wctx.

  7. Construct the entire URL by sending the RelayState value above to the identity provider STS. For example, if the identity provider STS is located at https://idp.fabrikam.com/adfs/ls/:

    https://idp.fabrikam.com/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID%3Dhttp%253A%252F%252Ffs.contoso.com%252Fadfs%252Fservices%252Ftrust%26RelayState%3DRPID%253Dhttps%25253A%25252F%25252Fwifapp%2526wctx%253Dappid%25253D47
    

Result

Upon browsing to the URL in step 7 above, the user should see the following:

  1. Depending on authentication type configured at the identity provider STS, an authentication prompt at the identity provider STS (only if previous authentication has not occurred).

  2. The browser will redirect and ultimately land at https://wifapp without any further user interaction.

Configuration Required

Once you have installed the Update Rollup 2 for AD FS 2.0 package and restarted the ADFS service, you must add a line to the web.config file in order for the feature to become active. Perform the following steps:

Note

The following steps are required on all AD FS federation servers and AD FS federation server proxy computers.

  1. Open the web. config file, located by default at C:\inetpub\adfs\ls\web.config

  2. Add the following entry to the <microsoft.identityServer.web> section:

    <microsoft.identityServer.web>
        ...
        <useRelayStateForIdpInitiatedSignOn enabled="true" />
    </microsoft.identityServer.web>
    

See Also

Concepts

Configuring Advanced Options for AD FS 2.0