Tag Archives: AD FS 2.0; Home Realm Discovery; Local Authentication Types

Home Realm Discovery– Supporting IWA and Forms Logon Local Authentication Types

A recent use case propped up where it was necessary to support multiple authentication types from a local AD FS instance in an internal access scenario. The mechanics for such a requirement are described in this great post here:

In our case, we’re substituting forms-based logon instead of the X509 client certificates described in the article. I’ve included a third MFA example to illustrate that additional legitimate claims providers can also be incorporated into the code changes.

There are two points of interest to us where an ADFS installation typically displays a user interface. The first is during the initial client logon to the federation server / proxy.  The other is during the home-realm discovery process. Home-Realm Discovery (HRD) is a pre-authentication drop-down box in AD FS that allows users to select their “home” realm, sending them to their identity provider for correct logon processing. In a normal RP-STS scenario, where AD FS is both an authentication provider and a relying party, this could be:

(a)    The default AD claims provider using Integrated Windows Authentication.

(b)   A third-party claims provider / identity provider

Both are valid claims providers in their own right, but I also needed to insert a third forms based “provider” option,  using local AD credentials, into this process. To do this, I used the customization of the HRD code-behind pages discussed in the post above.

First, to ensure that the appropriate realm selection screen is provided each time, we need to disable persistent cookie use for home realm discovery. This is achieved by changing Home Realm persistence in the AD FS web.config. This changes from

<persistIdentityProviderInformation enabled="true" lifetimeInDays="90"/>

to

<persistIdentityProviderInformation enabled="false"/>

Next, we’ll customize the local authentication types within the web.config so that Forms is the default logon method. More on this later…

<localAuthenticationTypes>

      <add name="Forms" page="FormsSignIn.aspx"/>

      <add name="Integrated" page="auth/integrated/"/>

      <add name="TlsClient" page="auth/sslclient/"/>

      <add name="Basic" page="auth/basic/"/>

 </localAuthenticationTypes>

 

When we click on this application, we see the HRD select screen, reflected in the following code in the homerealmdiscovery.aspx.cs code-behind page.

protected void Page_Init( object sender, EventArgs e )

{

 

PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

PassiveIdentityProvidersDropDownList.DataBind();

}

As the article mentions, we can add our own logic in the Page Init section of homerealmdiscovery.aspx.cs to customize this approach. The base.ClaimsProviders data source will normally return the list of “enabled” claims providers within ADFS. By modifying the code behind,we define the existing claims providers and our new forms authentication type.  In the following example, we’ve three providers. The provider called AD that will use IWA, an MFA provider that calls out to the third-party IdP  (MFA) and our new custom forms logon provider (Forms).

protected void Page_Init( object sender, EventArgs e )

{

 

PassiveIdentityProvidersDropDownList.Items.Add("AD");

PassiveIdentityProvidersDropDownList.Items.Add("MFA");

PassiveIdentityProvidersDropDownList.Items.Add("Forms");

 

}

 

We then modify the PassiveSignInButton section of the code behind to handle the appropriate authentication and redirection.

 

protected void PassiveSignInButton_Click( object sender, EventArgs e )

    {

   //SelectHomeRealm( PassiveIdentityProvidersDropDownList.SelectedItem.Value );

   switch (PassiveIdentityProvidersDropDownList.SelectedItem.Value)

        {

            case "AD":

                System.Web.HttpCookie cookie = new HttpCookie("MSISPAuthenticationMethod");

                cookie.Value = "AD";

                cookie.Path = "/adfs/ls";

                cookie.Domain = HttpContext.Current.Request.Url.Host;

                Response.Cookies.Add(cookie);

                Response.Redirect("https://&quot; + HttpContext.Current.Request.Url.Host + "/adfs/ls/auth/integrated/" + HttpContext.Current.Request.Url.Query);

                break;

 

            case "MFA":

              System.Web.HttpCookie cookie2 = new HttpCookie("MSISPAuthenticationMethod");

               cookie2.Value = "MFA";

               cookie2.Path = "/adfs/ls";

               cookie2.Domain = HttpContext.Current.Request.Url.Host;

               Response.Cookies.Add(cookie2);

           PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

               PassiveIdentityProvidersDropDownList.DataBind();

          SelectHomeRealm( "http://sts.anotherdomain.com/adfs/services/trust&quot; );

               break;

 

            case "Forms":

              System.Web.HttpCookie cookie3 = new HttpCookie("MSISPAuthenticationMethod");

               cookie3.Value = "Forms";

               cookie3.Path = "/adfs/ls";

               cookie3.Domain = HttpContext.Current.Request.Url.Host;

               Response.Cookies.Add(cookie3);

           PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

               PassiveIdentityProvidersDropDownList.DataBind();

           SelectHomeRealm( PassiveIdentityProvidersDropDownList.SelectedItem.Value );

            break;

 

   

            default:

                break;

        }

    }

}

In the first case, we invoke the Integrated Windows Authentication (IWA) handler.

In the second and third cases, we restore the original claims provider list,

PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;

    PassiveIdentityProvidersDropDownList.DataBind();

 

The second case invokes a third-party IDP by calling its home realm identifier. In this example, this is an upstream AD FS IdP recognizable via a http://sts.anotherdomain.com/adfs/services/trust identifer.

In the third and final case – forms logon, we simply select the default claims provider, which you’ll recall, given the order of the web.config has been changed to forms logon. I did this for expediency, as calling formssignin.aspx directly just generated an error.

Each time users connect, they’re now presented with the HRD dialog.

clip_image001[4]

As the folks from http://myitforum.com state in their post, to avoid irritating your users, you can set a cookie expiry period to persist the cookie  for a desired period for a given authentication method. In my test case, this wasn’t valid as users needed to regularly switch between various providers/authentication types. Of course, this has its own disadvantages from a convenience standpoint.

PS: Thanks to a developer buddy of mine, Nico, who continues to exhibit remarkable depths of patience to a  certain .NET neophyte J