This post is part of a series called “Windows Azure for the ASP.NET Developer” written by Rachel Appel, Adam Hoffman (that's me), and Peter Laudati. You can see the complete list of posts in the series at the US DPE Azure Connection site.
The timing of this post is pretty ironic, frankly. Yesterday, the world saw a very large company lose millions and millions of passwords to an attack. This post, which is part 2 of my mini-series on "multi-user applications in Windows Azure" describes an authentication method that keeps you from storing passwords in the first place.
In the previous post in this series, we discussed the tried and true “provider” method of adding multiuser support to your applications. In this post, we’ll take a look at an alternative that help us to solve some sticky issues.
The Shiny New Stuff (That Helps to Solve Some Sticky Problems)
How many times have you gone to a website and been asked to sign up for an account on the website? If you're like me, you have accounts for your various email accounts (I think I have about 7), your bank's website, LinkedIn (ahem...), Amazon.com, Sears.com, each of your credit cards, Home Depot, your car loans, insurance companies, doctor's offices, and probably dozens of geek sites, like Github, CodeProject, MSDN, and so on. I would guess that I have about 50 of these, and that's just the ones I remember now. Undoubtedly, I've abandoned many more over the years.
Also, to be sure that a hacker who steals passwords off of one of these sites doesn't then have access to my entire life, I create random, hard to remember passwords for everything, and then keep track of these in a password safe. At the end of the day, it's effective, but quite a hassle. It would be a lot easier if I could just remember fewer passwords...
And that's just from the user's point of view. Now imagine it from the developer's side: You might have noticed that while the previous providers technologies that help us to authenticate and authorize our users, we're still left in the uncomfortable situation of maintaining passwords in our own databases. That makes us a target, and adds a fair bit of responsibility to our applications. Yes, the passwords in our databases using the providers is encrypted, but that doesn't mean they'll always be unbreakable. I don't know about you, but as a developer, I'd much rather be able to authenticate my users without having to bear the responsibility of managing their passwords in my database. I'd like to not ever have to worry about implementing the whole series of administrative pages that are required for "forgot username", "forgot password" and "reset password" pages that a site which uses the providers must have. Is there another way?
Claims Based Identity to the rescue. Imagine a world where you can just know that the users who show up to your site are really who they claim they are. If I show up, and tell you that I am Adam Hoffman, you can just trust me and proceed under the assumption that I am, indeed, Adam Hoffman. Well, OK. Maybe that's a little too optimistic. How about if someone else that you really, really, really trusted told you that I was Adam Hoffman? That, in a nutshell, is how Claims Based Identity under the Windows Identity Framework (aka WIF) works.
Using Claims Based Identity in Windows, via the Authentication Control Service (aka ACS), your Azure applications can simply trust that the user is who they claim to be, and that the various data that the user claims about him or herself, like their name, email address, and so on, is accurate.
How does it do this? By trusting providers of identity services that we already have, like Microsoft Live ID, Google ID, Yahoo and Facebook. Most of us already have one of these types of identifications, and ACS allows us to simply reuse these authentication providers and trust them, similar to the way that we trust the local department of motor vehicles to provide our driver's license, or the passport agency to issue passports. When provided with a state issued driver's license, we assume that the claims on it (such as a person's name and birthdate) are valid. Similarly, when provided with information from a provider like Live ID, Google ID, Yahoo or Facebook, we can assume validity as well, because we trust Microsoft, Google, Yahoo and Facebook. By outsourcing the storage of account details and passwords to these trusted providers, we can simultaneously avoid storing passwords in our applications, and still be assured that our users are who they claim to be. In addition to being able to use these providers for authentication decisions, ACS also allows you to reuse your company's Active Directory by exposing it via ADFS (Active Directory Federation Services). In this way, you can even log into your Azure web applications using the same account and password that you use at work. For a virtual "chalk talk" on this subject, see the great video at http://aka.ms/ACSandADFS .
Visually, authentication using one of these trusted providers looks a bit like the following. In these diagrams, the Issuer used by Azure applications is provided by ACS:
OK, so this sounds great, but how can you do it? As it turns out, the process of using Live ID, Google ID or Yahoo ID is simple, and very similar. You can find step by step guides to supporting each of these three providers at:
The process of using Facebook is a little different. Essentially, in addition to the configuration of your application in Azure, you must also do a little more work in Facebook to obtain a Facebook Application ID and Facebook Application Secret. For a step by step walkthrough of this process, see http://aka.ms/ACSFacebookId .
Finally, if you're interested in exposing your company's Active Directory as an authentication provider, you'll likely need to do a little more work (and sometimes a bit of social engineering with your IT staff). Typically, you'll want to include certificates into the mix, in order to strengthen the security of the system and prevent tampering with the token provided by your Active Directory. To understand this process, check out the "chalk talk" video mentioned above, or see the walkthrough at http://aka.ms/ACSandADFSWalkthrough .
For more details on this, and an excellent overview of Claims Based Identity and Access Control, including the use of ACS in Azure, see the Patterns and Practice Group's guide at http://aka.ms/ClaimsBasedIdentity . For a practical walkthrough of ACS, including how to configure your ASP.NET application to use the ACS services, see the excellent MSDN article by Vittorio Bertocci and Wade Wegner at http://aka.ms/AzureACS .
So far, we've looked at outsourcing our authentication needs via ACS and WIF. This system generates a set of claims that we can use to make authorization decisions in our application, but by default, the various authentication providers pass through a relatively thin set of claims. For example, while Google ID passes along claims for "nameidentifier", "name" and "emailaddress" upon successful login, Live ID only provides "nameidentifier". ACS allows us to create rule sets to add additional claims to the token either through Token Transformation via Rules (seehttp://aka.ms/TokenTransformationRules) or by "enriching" these basic claims in a Claims Authorization Library. To create a Claims Authorization Library, we create a class that inherits from ClaimsAuthorizationManager, and override its Authenticate method. Typically, we would use an additional data store or some business logic that maps one of the available claims (typically "nameidentifier") to add the other claims that our applications require (like "ismanager" or "purchaselimit", etc.) Once we have these additional claims, we can then do our authorization. For a walkthrough of using your Claims Authorization Library to authorize your users, see http://aka.ms/ClaimsAuthorizationLibrary . For more on transforming claims in this library, see http://aka.ms/ClaimsTransformation . To really drive all this learning home, I highly recommend the lab at http://aka.ms/IdentityLab . This is a great example of securing a WCF Service, but the principles are the same as those for securing an ASP.NET application.
Most developers will find reasons from time to time to build secured ASP.NET applications and services. Doing this in Azure is quite simple using either the older provider techniques, or the newer claims based models.