Step-Up Authentication Scenario

Windows Identity Foundation
[Starting with the .NET Framework 4.5, Windows Identity Foundation (WIF) has been fully integrated into the .NET Framework. The version of WIF addressed by this topic, WIF 3.5, is deprecated and should only be used when developing against the .NET Framework 3.5 SP1 or the .NET Framework 4. For more information about WIF in the .NET Framework 4.5, also known as WIF 4.5, see the Windows Identity Foundation documentation in the .NET Framework 4.5 Development Guide.]

This scenario describes an application or Web site that has both low and high value resources, with different requirements for accessing those resources. It is common that an application or Web site initially authenticates the user with a low-strength authentication method, and later, when a user tries to access high-value resources, they are authenticated using a high-strength method.

The strength of an authentication method is application-specific; for example, some applications use password authentication as a low-strength authentication method, and smart card authentication as a high-strength authentication method. Other applications might use certificate authentication as a low-strength authentication method, and biometric fingerprint authentication as a high-strength authentication method. Regardless of the authentication methods used, the core aspects of this scenario are:

  • How an application communicates the required authentication method to the issuer, which is an STS.

  • How a service handles the request for a specific authentication method.

Since WIF is standards-based (WS-*) and supports WS-Federation Specification 1.2, it supports these core aspects.

The following diagram illustrates a typical step-up authentication scenario where a employee accesses low value and high value resources exposed in a application.


The fictional users participating in this scenario are:

  • Frank: The Fabrikam IT administrator and an employee trying to access Contoso resources.

  • Daniel: A Contoso application developer who implements the necessary changes in the application.

  • Adam: The Contoso IT administrator.

The components involved in this scenario are:

  • web1: A Web application with low value (LowValueResourcePage.aspx) and high value (HighValueResourcePage.aspx) resources, which uses a back-end web service to retrieve data from a SQL Server store.

  • sts1: An STS that is in the role of claims provider, and emits claims that are expected by the application (web1).

  • sts2: An STS that is in the role of identity provider for and provides two end points: one for a low-strength authentication method and one for a high-strength authentication method. It has established trust with so that Fabrikam employees are allowed to access the resources.

As shown in the previous diagram, the flow in this scenario is:

  1. The Contoso application is configured with the required claims to allow the Fabrikam user to access the protected low-value and high-value resources with the appropriate authentication methods. Daniel has implemented these application changes.

  2. The Fabrikam user, Frank, accesses Contoso’s application page and is, by default, signed in with a low-strength authentication method.

  3. The Fabrikam user, Frank, tries to access a high value resource and is prompted for step-up authentication to a high-strength authentication method.

Note that this sample scenario is for illustrative purpose only. The actual steps involved to achieve this scenario in a production environment might differ.

There are three options available for the administrator, Frank:

  1. Purchase and install an STS product such as Active Directory® Federation Services (AD FS) 2.0.

  2. Subscribe to a cloud STS product such as LiveID STS.

  3. Build a custom STS using WIF.

For this sample scenario, we assume that Frank selects option1 and installs AD FS 2.0 as the IP-STS. To support both low- and high-strength authentication methods, Frank exposes two end points from his STS: \windowsauth and \smartcardauth. By referring to the AD FS 2.0 product documentation, Frank establishes trust with the domain.

The options available for the administrator, Adam, are the same as described previously for the identity provider. For this sample scenario, we assume that Adam selects Option 1 and installs AD FS 2.0 as the RP-STS. By referring to the AD FS 2.0 Documentation, Adam establishes trust with and the application itself. He also configures the necessary claims required by the application to permit access to low-value or high-value resources.

The following changes extend the application to provide step-up authentication support:

The application can choose to require a custom claim, or the authenticationmethod claim emitted by default by the framework. The value of this claim needs to be a measure of strength of the authentication method. In this sample scenario, the authenticationmethod claim is flagged as a required claim. If the value of this claim is “CertorSmartcard”, the user is granted access to both the low-value and high-value resources. On the other hand, if the value of this claim is “windowsauth”, the user is granted access only to the low value resources.

For more information about the authenticationmethod claim and the possible values for various token types, see The Claims-Based Identity Model.

The application can specify the required authentication method to the claims provider through a parameter, wauth, which is defined in the WS-Federation specifications. Alternatively, the application can externalize all aspects of the authentication to the claims provider and specify an application-specific claim as a required claim (for example, the privilegelevel claim with the possible values “lowvalue” and “highvalue”).

In this sample scenario, the wauth parameter is used with possible custom values of “authstrength1” for low-value resources, and “authstrength5” for high-value resources.

The following code sample shows how the FederatedPassiveSignIn control can be used to tag the authentication strength values to pass them to the claims provider. Note that the AuthenticationType parameter is serialized as the WS-Federation wauth parameter on the wire.

AuthenticationType=https://WIFSample/authstrength1 ID="FederatedPassiveSignIn1" runat="Server" 
Issuer="" SignInButtonType="Link" 
TitleText="Click the link below to access low value resources" 
SignInText="Access low value resources"
Realm="" OnSignInError="FederatedPassiveSignIn_SignInError" 
DisplayRememberMe="false" VisibleWhenSignedIn="false">

The Contoso claims provider (sts1) processes the wauth parameter and redirects the user accordingly to an endpoint on the Fabrikam identity provider (sts2).

The application needs to establish trust to a claims provider so that tokens issued by the claims provider can be consumed by the application. Establishing Trust from an ASP.NET Relying Party Application to an STS using FedUtil can do this in two steps:

  1. Register the application: FedUtil downloads the federation metadata from the sts1 (the RP-STS) and the application, selects the necessary claims, and updates the application’s web.config file.

  2. Publish the application: FedUtil generates federation metadata for the application (a metadata.xml file) and places it in the application folder. This is accessible by the RP-STS through a simple HTTP GET.

For more information, see Establishing Trust from an ASP.NET Relying Party Application to an STS using FedUtil.

In order to make use of the claims for step-up authentication and other identity-related tasks, the application needs to enumerate claims from IClaimsPrincipal and check for the required claim authenticationmethod.

For detailed steps on how to make an application claims-aware, see the ASP.NET section of Building Relying Party Applications.

The following code sample shows how the high-value resource page checks for the authenticationmethod claim and makes sure that its value is “CertOrSmartcard” before granting access to the page. This code sample also shows how to redirect the user to a high-assurance sign-in page that triggers step-up authentication:

if ( Page.User.Identity.IsAuthenticated == true )
    if ( GetAuthStrengthClaim() != "CertOrSmartcard" )
// The user is authenticated with low assurance. Redirect to high assurance // sign-in page.
        Response.Redirect( "HighAssuranceSignInPage.aspx" );
// Otherwise, the user is successfully authenticated with high assurance.
// Allow access to high value resources.
// The user is not authenticated. Redirect him to "Default.aspx"
    Response.Redirect( "Default.aspx" );

private string GetAuthStrengthClaim()
    IClaimsIdentity claimsIdentity = (IClaimsIdentity)((IClaimsPrincipal)Thread.CurrentPrincipal).Identities[0];

// Searches for an Authentication Claim.
    IEnumerable<Claim> claimCollection = ( from c in claimsIdentity.Claims
where c.ClaimType == System.IdentityModel.Claims.ClaimTypes.Authentication
select c );
    if ( claimCollection.Count<Claim>() > 0 )
        return claimCollection.First<Claim>().Value;

    return String.Empty;

HighAssuranceSignInPage.aspx contains the FederatedPassiveSignIn control with a corresponding issuer endpoint and AuthenticationType parameter:

AuthenticationType=https://WIFSample/authstrength5 ID="FederatedPassiveSignIn1" runat="Server" 
SignInButtonType="Link" SignInButtonStyle-Height="50px" AutoSignIn="false" SignInText="High Assurance Sign-In"
TitleText="Click the below sign-in to authenticate with high assurance" 
Realm="" OnSignInError="FederatedPassiveSignIn1_SignInError" VisibleWhenSignedIn="true" DisplayRememberMe="false">
<SignInButtonStyle Height="50px" />

One of the challenging aspects of this scenario is to transparently append the elevated claims of the user upon successful step-up authentication.

The user is logged on with the initial authentication method (“windowsauth”) and issued a collection of claims (which we’ll call ClaimsCollectionA). When the user tries to access high-value resources, you redirect the user to the proper page for step-up authentication, as shown in the previous section. Upon successful re-authentication, a new collection of claims (which we’ll call ClaimsCollectionB) is issued. This new collection needs to be refreshed in the user’s identity so that when the application checks for high-value assurance the necessary claim is present.

The WSFederationAuthenticationModule handles this by refreshing its session security token with the latest claims received. This means that, when the user initially logs in with Windows authentication, the WSFAM issues a session security token with the appropriate claims; when the user performs step-up authentication to a certificate, the WSFAM sees that the user is already authenticated and that a new token has been issued, so it refreshes the session security token with the new collection of claims.

When the new authentication is received, the WSFAM will by default write out a new cookie containing only the new claims. If an RP application instead wants the second set of claims to be appended to the initial set, it should handle the SessionSecurityTokenCreated event from the control on the login page. At that point, the user has been authenticated with the old claims (in Thread.CurrentPrincipal) but the application also has access to the new claims in the event arguments, so it can merge them however it wishes before the new Thread.CurrentPrincipal is set. Whatever is set will be preserved in the new cookie.

WIF comes with a comprehensive list of samples. To see how WIF supports the step-up authentication scenario, see the sample End-to-end\Authentication Assurance. Note that this sample is intended to work on a single system with two custom IP-STSes and an RP.