With the R2 preview of AD FS in Windows Server 2012 out and the large number of changes that are taking place in the new release, I’m going to be bring this post to a quick end; more an abridged version than was originally intended.
In Part I we looked at weaker authentication schemes for step-up scenarios. In Part II, we move onto two-factor/multi-factor authentication (2FA/MFA) use cases.
There’s no real guided approach for doing this in AD FS 2.0, with solutions invariably becoming customized ones, according to the desired use case. Whether AD FS is the authentication provider or occupying a hybrid/broker role, the use of authentication contexts, types and URIs provided by the supported SAML and WS-Federation protocols, become triggers for step-up. Where a context is stipulated, in protocol terms, each is interpreted differently.
SAML supported authentication methods
|Authentication Method||Authentication Context Class URI|
|Password Protected Transport||urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport|
|Transport Layer Security (TLS) Client||urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient|
|Integrated Windows Authentication||urn:federation:authentication:windows|
As we saw in the previous post, forcing authentication in SAML logon scenarios provides support for step-up, but at the expense of single sign-on. In passive federation scenarios, if we don’t specify an authentication method in the request, AD FS will apply authentication according to its own supported methods, attempting to match those against the local authentication types section of the web.config on the AD FS node.
AD FS handles the SAML authentication in order of strength, lowest to highest, from top to bottom as seen in the table: in the default configuration Kerberos is seen as the strongest method. The precedence of the authentication method can be adjusted using the Set-ADFSProperties –AuthenticationContextOrder command to ensure the order meets the requirement we need. The SAML comparison attribute can be used to also influence the authentication method chosen. with AD FS defaulting to a comparison=exact attribute.. As stated in the MSDN article Authentication Handler Overview, if the comparison attribute is set to “better”, “minimum”, or “maximum”, the method of authentication must be stronger than, at least as strong as, or no stronger than one of the specified authentication classes. This gives us some latitude for using it to invoke the desired authentication method through customization of the sign-in process. With SAML the authentication reference is encoded in the SAML request, and to access and to use the information therein, in order to relay the authentication request to our third-party IdP, we need to customize our sign-in process so that the incoming SAML (AuthnContextClassRef) request is decoded. The information we then need needs to be extrapolated so that we can then make the correct routing decision, sending the client to the correct provider. Examples provided on Codeplex hint at how this can be done, by assigning a authentication methods to a relying party using FBA and IWA.
On the other side, let’s look at an example using a WS-Federation based setup.
WS-Federation Passive Profile supported authentication methods
|Authentication Method||Authentication Context (wauth) URI|
|Transport Layer Security (TLS) Client||urn:ietf:rfc:2246|
|Integrated Windows Authentication||urn:federation:authentication:windows|
With the WS-Federation passive requester profile, the authentication type (wauth) parameter is specified in the query string of the browser or can be specified from the relying party application itself. The whr parameter is used to indicate the claims provide to use for logon.
MFA Step-Up Scenario
Let’s look at a step-up scenario using WS-Federation with an MFA provider.
In the above graphic, we have a third-party MFA provider handling the authentication requests for internal access.. I’ve not included the AD FS Proxy for external access, but should we wish to do so, we could adopt our AD FS proxy configuration and:
– remove the local authentication handlers from the <localAuthenticationTypes> section of web.config to ensure that MFA is always used in external access scenarios;
– follow the same methods used for internal authentication described below;
Internal access step-up scenarios imply the use of the default Integrated Windows Authentication (IWA) handler and the step-up mechanism. With a third-party multi-factor authentication provider, the (MFA) solution is configured within AD FS 2.0 as a claims provider. I’ll use the example of the WIF-based STS from PointSharp which I mentioned in previous posts.
In a step-up context, the STS needs to be able to process the required authentication request and pass this back to AD FS and the RP. With WS-Federation we can do this via the browser as a query string, or, from the web application make use of the wauth and whr parameters to set the authentication method.
Step-Up at the Relying Party Application
Using the WIF 3.5 SDK samples for our relying party, we modify the web.config to specify the desired authentication type. I’ve chosen the X509 certificate handler. For our WIF application this corresponds to an authentication method value of urn:ietf:rfc:2246
<wsFederation passiveRedirectEnabled="true" issuer=https://sts.mydomain.com/adfs/ls/ realm=https://rp.mydomain.com/ requireHttps="true" authenticationType="urn:ietf:rfc:2246"
homeRealm=https://2sts.mydomain.com/PointsharpSTS <cookieHandler requireSsl="true" />
The homeRealm value is used to specify the claims provider we want to call for step-up, otherwise AD FS itself will attempt to handle the logon, treating as an authentication request for an x509 certificate.
On AD FS we configure the IP-STS as a claims provider.
On the IP-STS, we configure AD FS as a relying party
For convenience, both the STS and AD FS are sharing the same identity store (AD) and I’ve created a test user called demo in Active Directory and a security group called OTP, whom our user is a member of. We’ll use membership of that group on the PointSharp STS as a means of emitting an authentication method claim that corresponds to the expected authentication type. The claims value, urn:ietf:rfc:2246, is returned when a user logs on using MFA (e.g. OTP+password).
The user demo points their browser to the RP URL and with the web.config modifications, the access request is redirected to AD FS and then to the PointSharp STS as the Windows home realm (whr).
On the PointSharp STS during logon, the back-end PointSharp ID services handles the MFA logon request. At the initial prompt, the user enters their user ID and AD password:
They’re challenged to enter an OTP response (hardware/software token or SMS)
Once authenticated, the STS then processes the matching claims rules.
Above, demo is a member of the group OTP, as seen in the claims rule pattern, so a claims type of http://schemas/microsoft.com/ws/2008/06/identity/claims/authenticationmethod is generated. This is used to match the expected reply of the RP with a value urn:ietf:rfc:2246. and this claims is then passed back to AD FS.
In our test web app we see the appropriate authentication method and values being returned. No claims rules on the claims provider or relying parties (at this point) have been done.
Our MFA provider may also support multiple authentication types (AD password, SMS, tokens etc), so the fact that we logon at the STS is not necessarily indicative of a sufficient logon.With AD FS as the RP-STS, we can also block requests that don’t emit the correct authentication method at the STS on the relying party claims pipeline.
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value =~ "^(?i)http://schemas\.microsoft\.com/ws/2008/06/identity/authenticationmethod/tlsclient$"]
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "PermitUsersWithClaim");
With the authorization rule in place, another user, demo2, that is not a member of the OTP group, when accessing the RP, logs on at the PointSharp STS, but gets the following error at AD FS:
This translates in the event log to an access denied message:
The Federation Service could not authorize token issuance for caller ”. The caller is not authorized to request a token for the relying party ‘https://rp……..’. Please see event 501 with the same instance id for caller identity.
While we can block in this fashion, it makes more sense to enforce and evaluate a more fine-grained access at the application itself. If the app is intended as an internal-only application though, we can also block access from the AD FS proxy via an access rule.
exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”]) => issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);
Step-Up within the Application
The previous steps described step-up at the web application (relying party), rather than within the application itself. The WIF 3.5/4.0 SDK provides samples for step-up authentication using an example of a low-value and a high-value resource within a given application. Here we’re leveraging step-up against a particular resource within an application.
Low-value resources are protected using normal Windows logon credentials (IWA), whereas high-level resources trigger step-up through the use of the certificate handler.
This allows us to add in step-up authentication within the application itself, according to the value of the resource.
A note on Virtual Smart Cards
I mentioned in the last post about virtual smart cards (or VSCs). As an authentication provider, they are available during Windows logon as a credential provider. Given that we wish to expressly enforce step-up at the application, then some sort of adjustment is equired. It may be possible to suppress the use of the VSC as a credential provider and make it available post-logon for application-only access, something that I’ve not tried, but one could argue that this is a case of the tail wagging the dog. We could also use an alternate account as described in Part I or disable single sign-on in the web.config on the AD FS farm to enforce logon between relying parties. The fact that we’re using IWA for normal logon masks somewhat the behaviour of revisiting the AD FS server when switching between IWA-based relying parties.
As ever, please extensively test before considering doing this sort of thing in a production environment.
What’s been discussed so far relates to solutions that are on the “direct” authentication path from an identity federation standpoint. There are also MFA solutions that involve indirect authentication using multi-factor authentication. When I refer to Indirect MFA, Í mean some other component outside of the federation logon process that handles the strong authentication aspects of logon. Diagrams always help to illustrate the cause …
1. Via a non-federation capable proxy or gateway component. This component does not integrate with AD FS, but can provide an MFA capability. All connections to the RP are through the proxy. Post-logon, the proxy does some form of credential delegation to the back-end AD FS service. Here’s an example of a logon scenario with Forefront UAG 2010 on a non-federated trunk. While UAG does support federated trunks (as a relying party), MFA on a federated trunk is not (to my knowledge) possible unless we use an upstream claims provider.
2. Via an MFA web agent running on the ADFS proxy as an ISAPI filter or module. This follows the traditional web access management approach of logon via a web agent, with the filter intercepting the call. The user must logon using the stronger form of authentication before the web application, in this case the AD FS proxy pages are exposed. While functionally “integrated”, the two operate technologically independent of one another.
- 3. Via customization of the AD FS sign-in pages, allowing authentication to a MFA provider through web services. Of the three, this is (in my mind) is the most technically plausible, but handling step-up in such cases would also be complex and I’ll refer to that in a moment.
None of the above mechanisms are particularly well suited to step-up because the MFA logon process wraps around normal AD FS logon process, rather than integrating with it. While they may be valid in other access scenarios, i.e. the logon request is intercepted by a handler that doesn’t understand federated logon.
Option 3 is interesting as, via a slight modification, it supports illustrating where MFA is going in the next release of AD FS in Windows Server 2012 R2.
Windows Server 2012 R2
In AD FS R2, Microsoft are making available an MFA API for vendors to plug-in to and integrate with the federation service directly, allowing for a more rich logon experience. This also extends the concept of using multi-factor authentication not only at a protocol and application level, but at a policy level too, whereby policy per relying party for authentication is achievable. It also suggests that the redirect method via claims providers is being eschewed by Microsoft in favour of a more AD FS centric approach. I suspect the aim here is to provide a more level playing field for integrating external authentication providers with AD FS rather than placing the burden on the vendor and heavy use of customization to support scenarios described..
What this means for step-up scenarios we shall see. I’ll be looking at this raft of new features with AD FS R2 in future posts.