A Refresh of the Windows Azure Authentication Library Developer Preview

image

Three months ago we released the first developer preview of the Windows Azure Authentication Library. Today we are publishing a refresh of the developer preview, with some important (and at times radical) improvements.
We already kind of released this update, albeit in stealth mode, to enable the Windows Azure authentication bits in the ASP.NET Fall 2012 Update which is the result of a collaboration between our team and ASP.NET; we also used the new AAL in our in our end to end tutorial on how to develop multitenant applications with Windows Azure Active Directory.
In this post I will give you a quick overview of the main changes; if you have questions please leave a comment to this post (or in the forums) and we’ll get back to you! And now, without further ado:

The New AAL is 100% Managed

As mentioned in the announcement of the first preview, the presence of a native core of AAL was only as a temporary state of affairs. With this release AAL becomes 100% managed, and targeted to any CPU. This represents a tremendous improvement in the ease of use of the library. For example:

  • No more need to choose between x86 or x64 NuGets
  • No need to worry about bitness of your development platform
    • also, no need to worry about use ov IIS vs IIS Express vs Visual Studio Development Server
  • No need to worry about bitness of your target platform
  • No need to worry about bitness mismatches between your development platform and your target platform
  • No need to install the Microsoft Visual C++ Runtime on your target platform
    • access to target environments where you would not have been able to install the runtime
  • No native/managed barriers in call stacks when debugging

From the feedback we received about this I know that many of you will be happy to hear this :-)

The New AAL is Client-Only

The intention behind the first developer preview of AAL was to provide a deliverable that would satisfy the needs of both service requestors and service providers. The idea was that when you outsource authentication and access control to Windows Azure Active Directory, both the client and the resources role could rely on the directory’s knowledge of the scenario and lighten the burden of what the developer had to explicitly provide in his apps. Also, we worked hard to keep the details of underlying protocols hidden away by our AuthenticationContext abstraction (read more about it here).

Although that worked reasonably well on the client side, things weren’t as straightforward on the service/protected resource side. Namely:

  • Having a black box on the service made very difficult to troubleshoot issues
  • The black box approach didn’t leave any room for some basic customizations that service authors wanted to apply
  • In multi-tenant services you had to construct a different AuthenticationContext per request; definitely possible, but not a simplifying factor
  • There are a number of scenarios where the resource developer does not even have a tenant in Windows Azure AD, but expects his callers to have one. In those cases the concept of AuthenticationContext wasn’t just  less than useful, it was entirely out of the picture (hence the extension methods that some of you found for ClaimsPrincipal).

Those were some of the conceptual problems. But there were more issues, tied to more practical considerations:

  • We wanted to ensure that you can write a client on .NET4.0; the presence of service side features, combined with the .NET 4.0 constraint, forced us to take a dependency on WIF 1.0. That was less than ideal:
    • We missed out on the great new features in WIF 4.5
    • It introduced a dependency on another package (the WIF runtime)
    • Less interesting for you: however for us it would have inflated the matrix of the scenarios we’d have to test and support when eventually moving to 4.5
  • The presence of service side features forced us to depend on the full .NET framework, which means that apps written against the client profile (the default for many client project types) would cough

Those were important considerations. We weighted our options, and decided that the AAL approach was better suited for the client role and that the resource role was better served by a more traditional approach. As a result:

  • From this release on, AAL only contains client-side features. In a nutshell: you use AAL to obtain a token, but you no longer use AAL for validating it.
  • We are introducing new artifacts that will help you to implement the resource side of your scenarios. The first of those new artifacts is the JSON Web Token Handler for the .NET Framework 4.5 , which we are releasing in developer preview today. You can read more about it here.

This change further reduced the list of constraints you need to take into account when developing with AAL; in fact, combining this improvement with the fact that we are now 100% managed we were able to get rid of ALL of the gotchas in the release notes of the first preview!

I go in more details about the JWT handler in this other post, but let me spend few words here about its relationship with AAL. The first developer preview already contained most of the de/serialization and validation logic for the JWT format; however it was locked away in AAL’s black box. That made it hard for you to debug JWT-related problems, and impossible to influence its behavior or reuse that logic outside of the (intentionally) narrow scenarios supported by AAL. The JWT format is a rising star in the identity space, and it deserves to be a first class citizen in the .NET framework: which is why we decided to create a dedicated extension for it, to be used whenever and wherever you want with the same ease with which you use WIF’s out-of-box token handlers (in fact, with even more ease :-)). Some more details about this in the next section.

 

The Samples Are Fully Revamped

The three samples we released with the first developer preview have been adapted to use the new bits. The scenarios they implement remain the same, however the client side projects in the various solutions are now taking advantage of the new “anyCPU” NuGet package; you’ll see that very little has actually changed.

The projects representing protected resources, conversely, no longer have a reference to AAL. Instead, they make use of the new JWT handler to validate the incoming tokens obtained via AAL on the clients. The use of the JWT handler awards you finer control over how you validate incoming tokens.

Of course, with more control the abstraction level plummets: wherever with the old AAL approach you just had to initialize your AuthenticationContext an call Accept(), provided that you were on the blessed path where all settings align, here you have to take control of finding out the validation coordinates and feed them in. It’s not as bad as it sounds: you can still automate the retrieval of settings from metadata (the new samples show how) and the JWT handler is designed to be easy to use even standalone, in absence of the WIF configuration. Furthermore: we are not giving up on making things super-simple on the service side! We are simply starting bottom-up: today we are releasing a preview of token handling logic, moving forward you can expect more artifacts that will build on the more fundamental ones to give you an easier experience for selected scenarios, but without losing control over the finer details if you choose to customize things. Stay tuned!

IMPORTANT: the samples have been upgraded in-place: that means that the bits of the samples referring to the old NuGets are no longer available. More about that later.

Miscellaneous

There are various targeted improvements here and there, below I list the ones you are most likely to encounter:

  • For my joy, “AcquireUserCredentialUsingUI” is no more. The same functionality is offered as an overload of AcquireToken.
  • There is a new flavor of Credential, ClientCredential, which is used to obtain tokens from Windows Azure Active Directory for calling the Graph on behalf of applications that have been published via the seller dashboard (as shown in the Windows Azure AD session at //BUILD). You can see that in action here.
    In the spirit of empowering you to use the protocol directly if you don’t want to rely on libraries, here there’s what happens: when you feed a ClientCredential to an AuthenticationContext and call AcquireToken AAL will send the provided key as a password, whereas SymmetricKeyCredential will use the provided key to perform a signature.
  • You’ll find that you’ll have an easier time dealing with exceptions

The Old Bits Are Gone

If you made it this far in the post, by know you realized that the changes in this refresh are substantial.
Maintaining a dependency on the old bits would not be very productive, given that those will not be moved forward. Furthermore, given the dev preview state of the libraries (and the fact that we were pretty upfront about changes coming) we do not expect anybody to have any business critical dependencies on those. Add to that the fact that according to NuGet.org no other package is chaining the old bits: the three AAL samples were the only samples we know of that took a dependency on the AAL native core NuGets, and those samples are being revamped to use the new 100% managed NuGet anyway.

For all those reasons, we decided to pull the plug on the x86 and x64 NuGets: we hope that nobody will have issues for it! If you have problems because of this please let us know ASAP.

What’s Next

Feedback, feedback, feedback! AAL is already used in various Microsoft properties: but we want to make sure it works for your projects as well!
Of course we didn’t forget that you don't exclusively target .NET on Windows desktop; please continue to send up feedback about what other platforms you’d like us to target with our client and service libraries.

We are confident that the improvements we introduced in this release will make it much easier for you to take advantage of AAL in a wider range of scenarios, and we are eager to hear from you about it. Please don’t be shy on the forums :-)