I recently had a client ask me for guidance on token-based authentication options for their enterprise. They provided a set of requirements that were roughly as follows:
- Session-based authentication so re-authentication didn’t happen on each message sent
- “Plug-and-play”-ability with a slew of RESTful Service Web APIs as well as existing externally-facing ASP.NET web sites
- Use Active Directory as a repository for internal users
- Use existing ASP.NET membership stores for external users, which already contain accounts created via FBA registration
After doing some analysis, I determined that Windows Azure Access Control Services (ACS) is a great fit for this scenario. Below, I’ll explain why.
What is ACS?
Windows Azure ACS is a cloud-based authentication service that uses Identity Providers to easily authenticate and authorize users. It can be leveraged by nearly every platform for web development in use today and has built-in support for many popular identity providers, including Facebook, Google, Yahoo, & Windows Live Id. For a full MSDN description of ACS, click here.
Why does ACS work in this scenario?
Windows Azure ACS not only supports a set of very popular identity providers; it also has a key extensibility point that allows us to fulfill our client’s needs: the ability to integrate with custom Identity Providers. This integration requires that the providers be either WS-Federation protocol, such as Active Directory Federation Services (ADFS), or Open ID protocol compliant. The included support for ADFS solves Requirement #3 right away. But what about the other requirement of using existing ASP.NET membership databases as an identity repository? Turns out there are two very viable solutions to this problem: 1) Extending via WS-Federation Protocol, or 2) Extending via OpenID protocol.
WS-Federation Protocol Extensibility
To utilize an extension to the WS-Federation Protocol, the first step is to implement a Security Token Service (STS) that returned standard SAML tokens using the WS-Federation protocol (see here). Adding such a provider can be achieved in ACS by selecting the ‘Add ADFS 2.0 Identity Provider’ option. This option isn’t really bound to ADFS, but rather the WS-Federation protocol upon which ADFS was built. Third party solutions exist to expose an ASP.NET membership store as an STS, with http://identityserver.codeplex.com being a very prominent open source option.
If using a framework such as IdentityServer doesn’t work due to some unknown requirement, in-house solutions can be developed via the Windows Identity Framework (WIF). WIF is the basis for ADFS and can be used to do any claims-based authentication. In fact, the WIF SDK not only has a Visual Studio project template; it also has a really nice set of code examples, which can be found here. Also, the Microsoft Connect site has a fantastic code sample available for download here that shows how to issue tokens for Forms Authenticated users that are served up by an ASP.NET Membership Provider using WIF.
OpenID Protocol Extensibility
The second option is to leverage the OpenID protocol (endorsed by Google) by creating an OpenID provider that works with an ASP.NET membership schema. A nice C# framework already exists for this called DotNetOpenAuth that has been endorsed by http://openid.net. The code samples included with DotNetOpenAuth are extensive, and the OpenIdProviderMvc sample demonstrates how to implement the provider with a backing ASP.NET Membership provider (i.e. ASP.NET Forms-based Auth).
My research indicates that Windows Azure ACS is a good solution for my client’s need for a horizontal authentication layer that satisfies their requirements. I think the selection of Identity Provider protocols for issuing tokens will come down to enterprise strategy and the comfort level of the development team. Both protocols are widely used and well known. One advantage to using WS-Federation and the Windows Identity Framework is that the issued tokens will be identical to those issued by Active Directory Federation Services (ADFS) for the client’s domain (internal) users.
-Nick Nieslanik, VP of Engineering