This post refers to additional logon schemes that can be supported in AD FS by forcing users to re-authenticate or step-up/step-down authentication to federated web applications. It was prompted by a recent request from a customer :
“We wish to connect a SAML 2.0 Service Provider (SP) to AD FS. For security reasons, we require our internal users to logon (again) when connecting to this web application. All users connecting through the AD FS proxy should be prohibited access.”
Whether we choose to call this process re-authentication or step-up authentication really depends on the access case. To meet the requirement, we’ll be breaking single sign-on (SSO) when accessing the web application above by sending parameterised requests from the web application to AD FS, specifying how to handle authentication uniquely for this app.
Some folks may have pre-conceived ideas about what constitutes step-up, perhaps because it is often associated with multi-factor authentication. While the two do complement one another nicely, step-up is not necessarily multi-factor. Rather, use of step-up as an access mechanism, is governed by the strength of authentication we wish to accrue to access, at a level commensurate with requirements for protecting that resource. We can use weaker (single factor) authentication where this is deemed sufficient or appropriate. As an example, a customer may employ two-factor authentication on the outside/edge for all users and then elect to use the AD password, as an additional step-up mechanism for corporate users only to gain access to internal resources. In authentication strength terms, this is step-down authentication, but in functional terms, it’s designed as a step-up method.
I make the above point, because in the examples described here, we have users logging onto their workstations either using weak (username/password) or strong (two-factor) authenticating against other federated web applications with these credentials. In each case, we plan on forcing users to logon again when they access this particular SAML 2.0 web application to “step-up” security.
This is an internal only access scenario for the enterprise, meaning that users connecting via the AD FS Proxy should be denied access. Since AD FS Rollup 1, we’ve been able to specify Issuance Authorization Rule on the relying party (SAML 2.0 SP) pipeline that allows requests sourced from the AD FS Proxy to be identified and acted on via the claim description: http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy
Accordingly, we’ll create a deny Issuance Authorization Rule on our SAML web application so that users connecting through the proxy will be blocked.
exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”]) => issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);
In a default AD FS farm setup, a domain-joined Windows machine internal user connects to the AD FS farm and authenticates via the Integrated Windows Authentication (IWA) handler using Kerberos/NTLM. To alter this behaviour, for a given application, and force the user to re-authenticate, we must ignore the existing session cookie.
With WS-Federation, we can do this at AD FS, via a smart link, by specifying the wauth parameter:
For a relying party using the WS-Federation Passive Requester Profile (WS-PRP) we can also specify the request in the query string or within application code also via wauth.
This is a SAML 2.0-based use case though. As a backgrounder, I suggest reading about SAML Authentication Context Classes and Strengths with AD FS. Within the SAML 2.0 protocol, SAML service provider (SP) can emits certain values in the SAML request that ensures that the required authentication method from the SP is honoured by AD FS. From an SAML 2.0 protocol standpoint, this may be accomplished by:
Setting an Authentication Context Class Reference (AuthnContextClassRef) in the requested authentication context from the Service Provider;
Specifying the use of Force Authentication (ForceAuthn) in the request set to a value of true;
Use of a Comparison rule that is set to exact to expressly set the authentication method. Other settings are also possible (which AD FS supports) but are not covered in this post.
Let’s look at the farm-connected conventions mentioned above in a bit more detail.
Authentication Context Class Reference
In Windows SSO logon scenarios, the AD FS integrated handler uses the SAML AuthnContextClassRef of urn:federation:authentication:windows. On our SAML 2.0 web application, we’ll request a authentication context class reference of urn:oasis:names:tc:SAML:2.0:ac:classes:Password, so that the forms handler (in AD FS) is targeted as the desired authentication handler.
The specification of ForceAuthn=true in the initial SAML request from the service provider specifies that the Identity Provider (IdP) should force re-authentication of the user, even if they possess a valid session with AD FS.
The SAML 2.0 protocol supports the use of a comparison rule to determine the level of precision to be accorded to the authentication request. If none is specified, AD FS will assume that the attribute is set to exact, meaning that authentication should conform exactly to the AuthnContextClassRef request and is passed to the appropriate handler.
Configuring Service Providers
I’ve used two examples here:
I also planned on including Shibboleth, but hosed my configuration in the process, by reverting the wrong Snapshot of my VM during testing.. *cough*… sorry about that
Using OpenAM as a SAML SP example, we’ll invoke SP-initiated sign-on through the spSSOInit.jsp page. In the query string we’re specifying the authentication context and the desired force authentication.
https://myapp.mydomain.com/openam/saml2/jsp/spSSOInit.jspmetaAlias=/acs/sp&realm=acs &ForceAuthn=true&AuthnContextClassRef=urn:oasis:names:tc:SAML:2.0:ac:classes:Password &idpEntityID= http://adfs.mydomain.com/adfs/services/trust&RelayState=https%3A%2F%2Fmyapp.mydomain.com%2Fopenam%2Fconsole
Note: The above syntax is valid but watch out for white spaces in the example above, not to mention your own domain name. I’ve added spaces to make the text more legible.
AD FS will parse the request based on the emboldened items in the query string and ask the user to re-authenticate via forms sign-in.
In SimpleSAMLphp, we can set the necessary settings in the configuration file authsources.php, specifying the authentication context and force authentication requirement.
‘ForceAuthn’ => TRUE,
‘AuthnContextClassRef’ => ‘urn:oasis:names:tc:SAML:2.0:ac:classes:Password’,
How we choose to implement our step-up/re-authentication component depends on the question of sufficiency and what is an acceptable method to choose. For this exercise, this could mean:
re-using the Windows logon identity (re-authenticate);
using an alternate identity from within the same AD forest (step-up);
using an alternate identity residing in a connected forest (step-up);
using an alternate authentication service; a third-party application that provides stronger forms of authentication
Option 1 – Re-Authentication
The simplest option sees the the user replaying their AD credentials, logging on again via the AD FS form, before gaining access to the web application. This is clearly not step-up and doesn’t afford any significant additional protection, , but may fulfil compliance/auditing requirements for access.
|Simple (uses same identity)||Re-authentication not step-up authentication (same password policy)|
|Protects against inadvertent access to the application if the user is already logged on (e.g. where user fails to lock OS)||
Security gain is nominal. Requires claims authorization rules on the relying party to differentiate between valid/invalid users.
Option 2 – Step-Up Same Forest (username/password)
Option 2 uses another set of credentials held within the same AD FS forest. Access to the SaaS application is limited to those users using these credentials (i.e. their “step-up” identity) and an authorization rule to supplement this.
|Authentication is stepped using another identity besides the corporate logon||More complex. Requires additional identity to represent users (user management)|
|Supports use of stronger password policies on the second identity||
Security gain is moderate. Same factor (username / password) for step-up identity
|Less user friendly (extra identity)|
|Shared authentication sources between identities (no isolation)|
Option 3 – Step-Up Connected Forest (username/password)
A more complex rendition of this using multiple forests with a single AD FS instance (Option 3):
In the above setup we have an account forest for our corporate users and a resource forest, where the AD FS server lives (with the AD FS application pool account running in the account forest). A one way forest trust between the two exists. In this option, the step-up identities reside in the resource forest.
|Authentication is stepped using another identity besides the current logon||
More complex. Requires additional identity / shadow account represented in the remote forest (user management)
|Supports use of stronger password policies on the alternate identity||
Security gain is moderate. Same factor (username/ password) for step-up identity
|Shadow account can use same sAMAccountName in remote forest||Less user friendly (extra identity)|
|Greater isolation / independence of action from account forest (supports selective authentication)||More complex to manage|
For Options 2 and 3, we can also provide further refinement by using AD fine-grained password policies to implement a stronger password policy / account lockout policy applicable to our web application, that exceeds the ordinary password policy levels used for for corporate AD users.
In all above cases, we should consider further restraining access by passing custom claims on the relying party, to assist in determining whether the user in question should have access.
From an AD FS standpoint, there are no configuration changes required in the cases described thus far. You may note, however, that I’ve not yet mentioned IdP-Initiated Sign-On methods. SHAME! Well, there’s a couple of reasons for this, by which I’ll conveniently recuse myself
Firstly, there a nice solution posted on CodePlex, that works similar to the actions described in this post, albeit by customizing the AD FS sign-in pages instead. It allows assigning the use of forms logon logic to relying parties and also covers IdP-Initiated Sign-On and WS-Federation. Relying parties registered to use the forms logon are registered in AD FS web.config file, thereby bound to the forms handler.
Also, some customers may be unwilling to modify their default AD FS setup because of a fear that it will throw them outside the realms of Microsoft support. However, if you do wish to support IdP-Initiated sign-on scenarios using the methods above (AuthnContextClassRef and ForceAuthn), then I’m afraid you don’t have much choice as customization of the code-behind page for idpinitiatedsignon.aspx.cs is required. Without these changes, sign-on, either via logintoRP or relaystate query parameters, will fail as the desired authentication context (AuthnContextClassRef) has not been set and is not passed by the IdP to the service provider. I used the following MSDN article as a reference to customize the idpinitiatedsignon.aspx.cs and then tested this using logintoRP parameter, with the query string example below.
In Part II, we’ll look at step-up options with stronger / multi-factor authentication methods (aka Option 4). See ya!