Step-Up Authentication Scenario
[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 Fabrikam.com employee accesses low value and high value resources exposed in a Contoso.com 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 Fabrikam.com 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 Contoso.com so that Fabrikam employees are allowed to access the Contoso.com resources.
As shown in the previous diagram, the flow in this scenario is:
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.
The Fabrikam user, Frank, accesses Contoso’s application page and is, by default, signed in with a low-strength authentication method.
The Fabrikam user, Frank, tries to access a high value resource and is prompted for step-up authentication to a high-strength authentication method.
Basic Steps Involved in this Scenario
Note that this sample scenario is for illustrative purpose only. The actual steps involved to achieve this scenario in a production environment might differ.
Set Up the Identity Provider (IP)
There are three options available for the Fabrikam.com administrator, Frank:
Purchase and install an STS product such as Active Directory® Federation Services (AD FS) 2.0.
Subscribe to a cloud STS product such as LiveID STS.
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 Contoso.com domain.
Set Up the Claims Provider
The options available for the Contoso.com 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 Fabrikam.com and the application itself. He also configures the necessary claims required by the application to permit access to low-value or high-value resources.
Application-Specific Changes
The following changes extend the application to provide step-up authentication support:
Identify the claims required (that is, the strength of the authentication methods) for the low-value and high-value resources.
Establish trust to a claims provider using Establishing Trust from an ASP.NET Relying Party Application to an STS using FedUtil.
Make the application claims-aware.
Implement the transition from low-strength to high-strength authentication.
Identify the Claims Required for the Low-Value and High-Value Resources
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.
<wif:FederatedPassiveSignIn
AuthenticationType=https://WIFSample/authstrength1 ID="FederatedPassiveSignIn1" runat="Server"
Issuer="https://sts1.contoso.com/AuthPassive/Default.aspx" SignInButtonType="Link"
TitleText="Click the link below to access low value resources"
SignInText="Access low value resources"
Realm="https://web1.contoso.com/AuthAssuranceRP/Default.aspx" OnSignInError="FederatedPassiveSignIn_SignInError"
DisplayRememberMe="false" VisibleWhenSignedIn="false">
</wif:FederatedPassiveSignIn>
The Contoso claims provider (sts1) processes the wauth
parameter and redirects the user accordingly to an endpoint on the Fabrikam identity provider (sts2).
Establish Trust to a Claims Provider Using the FedUtil Tool
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:
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.
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.
Make the Application Claims-Aware and Trigger Step-Up Authentication
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.
}
else
{
// 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:
<wif:FederatedPassiveSignIn
AuthenticationType=https://WIFSample/authstrength5 ID="FederatedPassiveSignIn1" runat="Server"
Issuer="https://sts2.fabrikam.com/AuthPassiveSTSCert/Login.aspx"
SignInButtonType="Link" SignInButtonStyle-Height="50px" AutoSignIn="false" SignInText="High Assurance Sign-In"
TitleText="Click the below sign-in to authenticate with high assurance"
Realm="https://web1.contoso.com/AuthAssuranceRP/HighAssuranceSignInPage.aspx" OnSignInError="FederatedPassiveSignIn1_SignInError" VisibleWhenSignedIn="true" DisplayRememberMe="false">
<SignInButtonStyle Height="50px" />
</wif:FederatedPassiveSignIn>
Transparently Elevate to New Claims Collection After Successful Step-Up Authentication
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.
Sample Resources
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.