Windows Identity Foundation (WIF): How to Utilize the WS-Federation WHR Parameter to Bypass Home Realm Discovery (HRD)
There are two ways in which Windows Identity Foundation (WIF) can utilize the WS-Federation passive WHR parameter to bypass home realm discovery (HRD). There are a few questions to ask before deciding which method to implement:
1. Can the WHR parameter remain static for a Relying Party (RP) application?
**
**Meaning: The identity provider (IDP) always remains the same for this RP application. This application would be a single instance which is always accessed by users from the same IDP.
2. At what point in the authentication flow is the WHR parameter injected?
**
**Possibilities include: The requestor (the user agent) or the WIF RP. This goes hand-in-hand with question number 1 because you might only want the WIF RP to inject WHR when the IDP can be static. If the administrator is handing out or publishing links to the WIF RP which include a WHR value, then you would want to implement the change which allows the requestor to inject WHR.
Usage Examples
WHR injection by requestor
1. The user agent utilizes a link to the WIF RP with WHR appended
Example: https://myApp.contoso.com/?WHR=*insert-IDP-URI-here
*2. The WIF RP detects WHR in the incoming request and sets homeRealm to the value being passed in
WIF builds the WS-Federation sign-in request containing WHR and redirects the user agent to the RP-STS
The RP-STS detects the presence of WHR in the sign-in request and bypasses HRD.
Note: Detecting and utilizing WHR at the STS is built into Microsoft's Active Directory Federation Services (AD FS) 2.0 product. If you have written your own WIF STS or are using a third party STS, you will need to ensure that your STS can work with the WHR parameter. For guidance on configuring a WIF STS to accept WHR, see the More Information section of this article.
WHR injection by WIF RP
1. The user agent utilizes a link to the WIF RP
Example: https://myApp.contoso.com/
The WIF RP builds a WS-Federation sign-in request with the hard-coded homeRealm value specifiied in its web.config file
The WS-Federation sign-in request containing the hard-coded WHR parameter is sent to the RP-STS via redirect
The RP-STS detects the presence of WHR in the sign-in request and bypasses HRD.
Note: Detecting and utilizing WHR at the STS is built into Microsoft's Active Directory Federation Services (AD FS) 2.0 product. If you have written your own WIF STS or are using a third party STS, you will need to ensure that your STS can work with the WHR parameter. For guidance on configuring a WIF STS to accept WHR, see the More Information section of this article.
Code Samples
This code is provided "AS IS" with no warranties, and confers no
**
rights. For more information please visit** http://www.microsoft.com/info/cpyright.mspx
to find terms of use.
**
**
WHR injection by requestor
1. Add a global.asax file to your web application
- Add the following code:
<%@ Application Language="C#" %>
<%@ Import Namespace="Microsoft.IdentityModel.Web" %>
<script runat="server">
void WSFederationAuthenticationModule_RedirectingToIdentityProvider
(object sender, RedirectingToIdentityProviderEventArgs e)
{
string strWhr = HttpContext.Current.Request.QueryString["whr"];
if (strWhr != null)
{
** e.SignInRequestMessage.HomeRealm = strWhr; **
**
** }
}
</script>
WHR injection by RP
Edit the <federatedAuthentication> element of the RP web.config to include homeRealm
Example:
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true"
issuer="https://localhost/BasicWebSite_STS/"
realm="https://localhost/BasicWebSite/"
**homeRealm="insert-IDP-URI-here"
** requireHttps="true" />
<cookieHandler requireSsl="true" />
</federatedAuthentication>
More Information
Utilizing WHR in a custom WIF STS
1. Add a global.asax file to your custom WIF STS
- Add the following code:
<%@ Application Language="C#" %>
<%@ Import Namespace="Microsoft.IdentityModel.Web" %>
<script runat="server">
void WSFederationAuthenticationModule_RedirectingToIdentityProvider
(object sender, RedirectingToIdentityProviderEventArgs e)
{
string strWhr = HttpContext.Current.Request.QueryString["whr"];
if (strWhr != null)
{
e.SignInRequestMessage.BaseUri = new Uri(strWhr);
}
}
</script>