When I was at TechEd this year, I ran into a few people asking how to integrate SecurID authentication into ADFS. As it currently stands, Microsoft has no direct support for this, or any other authentication mechanism besides AD/ADAM password authentication and client certificate auth. Hopefully in the future, Microsoft will make the account store and authentication mechanisms a first class extensibility point, but for now, we must hack. :)
As you can probably tell by the article title, I have gotten this working in my organization's environment, even though it is not supported by MS. So, how do we make this work? First, I'll explain the overall principles of how we glue these things together and then I'll share how I actually did it. In part 2 of the posting, I'll talk about some other ways that we might get this working.
Basic Principles
In Windows Server 2003 and Active Directory 2003, Microsoft implemented an important and useful extension to the Kerberos authentication protocol called "Service for User" (S4U), aka Protocol Transition. S4U adds the ability for a service to authenticate a client with a non-Kerberos protocol and then transition to a Kerberos-based identity for accessing Windows resources on local or remote services (hence "protocol transition"). Protocol transition is something that can be done automatically by services like IIS when a user authenticates with Basic, Digest or NTLM, but it can also be called programmatically and used by non-Windows authentication systems such as SecurID.
To use S4U, your code must execute on a Windows Server 2003 machine (or higher) AND your Active Directory must be 2003 forest functional level. If you are doing ADFS, you already have the former. However, since ADFS supports both Windows 2000 Server and Windows Server 2003 AD, you might not have the latter. If you don't, you are basically SOL for now. Upgrade!
When using S4U programmatically, you are basically calling the Windows API LsaLogonUser with the S4U option specified. When usings the S4U option, LsaLogonUser only requires you to know the user's UPN, not their password, in order to get a Windows logon token for them. There are some restrictions on how this token can be used, but that really isn't too important for this discussion. Keith covers this stuff in detail in his book and several articles anyway. One other nice thing is that .NET (as of 1.1 and higher) has a very easy way to call LsaLogonUser for S4U with the WindowsIdentity constructor that just takes the UPN. It is that simple.
So, now we know we need to use S4U to get a Windows token for the user and we'll need their UPN to call this. How does the Windows token then help us with ADFS? Well, the ADFS logon service (LS) has a method that allows a user to authenticate given their Windows token. In fact, the /ls/auth/integrated directory on the federation server does just this. It is set to use Windows Integrated authentication (IWA) in IIS. IIS logs the user on with IWA, passes the corresponding Windows token to ASP.NET. Then, the ADFS HTTP Module grabs that and calls the correct method to log you into ADFS and now you have a federation token.
An interesting side note is that ADFS itself uses protocol transition in the web agent for token-based applications to achieve similar things (assuming again that you have 2003 AD; otherwise it uses its custom authentication package).
So, our basic approach with SecurID authentication is to:
This is cake! :)
How I Did This
Ok, I cheated a little bit. In addition to using RSA's SecurID/ACE Server product in our company, we also use their ClearTrust web SSO product (now apparently called Access Manager, but I didn't get that memo). ClearTrust already basically let's me do steps 1-3 above using their standard product when the protocol transition/S4U feature is enabled. Since it runs as an ISAPI Filter/ISAPI Extension (via a wildcard map in IIS), it runs before any .NET code executes. All I had to do was configure ClearTrust on my /ls/auth/integrated directory, and ADFS doesn't know the difference between IIS having used IWA or some other thing. The LS just grabs the Windows token from where it expects to find it in ASP.NET and proceeds with logon. It really is cake and actually worked the first time I tried it.
The hardest part was instructing ClearTrust to NOT execute on any resources other than the /ls/auth/integrated directory, which essentially came down to a lengthy URL exclusion list in the ClearTrust configuration. Anyone who has used ClearTrust probably already knows how to do that. I will probably experiment with alternate directory structures to simplify this a bit more in the future.
Since ClearTrust is a web SSO product, it also contains a signout function that is implemented by navigating to a page. We integrated this into the ADFS signout by using the same technique it does: we referred to the ClearTrust signout page in a hidden image tag on the normal signout page. That results in our ClearTrust cookie being cleared.
One thing I should make clear is that we did this customization on the FS, not the FS-P (Federation Service Proxy). I don't see a reason why you couldn't do this there too, but you'd need to mess with it a bit more as the FS-P is configured out of the box to do its own forms auth instead of redirecting to the /ls/auth/integrated directory.
One important caveat with SecurID auth is that it basically requires forms authentication, especially to support PIN operations. This basically implies that you can't use the "basic" authentication support built in to ADFS here. As such, you should probably turn off that option in your ADFS configuration. That may also mean that you some SharePoint/Office integration stuff breaks though. I'm not sure how to reconcile that problem. Forms auth and Office don't like each other.
Summary
So anyway, that's the basic concept. If anyone needs additional details, let me know and I'll try to expand on this.
In Part 2 of this post, I'll try to expand on how one might accomplish if one were not so blessed with a working ClearTrust infrastructure in place to do the hard part. Note that I've never actually done this part, so some of it might just be wild supposition and it might take some help from someone else out there who really wants this to make it happen. We'll see. In the meantime, I hope the blueprint was helpful.
Remember Me
Theme design by Jelle Druyts
Powered by: newtelligence dasBlog 1.9.6264.0
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2008, Joseph E. Kaplan
E-mail