Claims-Based Identity in ASP.NET
This blog post will give you a general idea of the new authorization techniques provided by claims used by Windows Identity Foundation (WIF) and ASP.NET 4.5. I will try to explain what they are, how they get imported into your application, and how the resulting claims get translated into code that is used in an ASP.NET 4.5 application.
Why use claims?
Claims-based security is a type of security where the user’s identity is checked and confirmed by a third party outside of your application. In other words, your application, known as the relying party (RP), will no longer need to have a login page, or any code that validates passwords, user names, etc. No more account creation, password resets, etc. This is known as decoupling the security from your application.
What is a claim?
Previous security models required you, the developer, to create users and roles and then to assign roles to users. Your authorization logic then checked if roles were allowed to do something in your application. That was known as Role-Based authorization. But if you look at it from another angle, you can also describe it as a claim: “User John claims to be in the role called Administrator”. Think of the role as a “claim type”.
However, with claims-based security, a user can claim a lot more than just the roles he or she is in. For example, a user can claim their age to be a certain value, or their email to be a certain value. The possibilities are endless, and not just limited to roles.
Earlier, I said that you no longer need to provide a login page in your application if you use claims-based authentification. As the developer, you will receive what is called a secure token from the third party, inside which you will find a list of the user’s claims. You will use these claims to map what the user can and cannot do in your application. Think of the token as a driver’s license and the third party as the driving authority that issued the license and that you trust.
Who is the third party?
The third party is known as a Security Token Service (STS) or Identity Provider (IP) and acts as an issuing authority that accepts incoming credentials, validates them, and then creates a secure token with the list of claims. In other words, another trusty web site will do this for you.
Tokens are encrypted and sent to your application. It is important that the issuer of the token be a trusted entity. Examples are Microsoft, Facebook, or Google.
Microsoft offers two STS’s:
How does the process begin?
Each prospective will connect to your application through a browser. Upon their first request, and assuming that the WIF is configured properly, your application will see that the user is not authenticated, redirecting them to the STS. The STS will provide a login page where the user will enter credentials. If successful, the STS will issue a token to the user. The user will then be redirected back to your application with the token supplied in the request.
Your application is configured to trust the STS and the tokens it issues so that when it receives the token in the request, it will parse the token using the required WIF API. You will use this API to customize security for your application. Once parsed, your application will have the information it needs to allow or disallow the user from performing actions.
How do you implement it?
A custom security token will look something like the following when your application receives it. It is basically an XML file with a list of claims contained as
<m:thecustomtoken m:audience="https://yourwebsite/" m:id="”anID”" m:issuer="”urn:AnyIssuer”" m:validfrom="”2016-01-01”" m:validto="”2016-12-31”" xmlns:m="”urn:thecustomtoken”">
<m:claim name="”FirstName”" namespace="”urn:firstname”">Ray</m:claim>
<m:claim name="”LastName”" namespace="”urn:firstname”">Cacciatore</m:claim>
<m:claim name="”Role”" namespace="”urn:firstname”">Administrator</m:claim>
<signature xmlns="”http://www.w3.org/2000/09/xmldsig#">
<signedinfo>
…
</signedinfo>
</signature>
</m:thecustomtoken>
When working with a user’s identity in an ASP.NET application, developers traditionally implement the IIdentity and IPrincipal interfaces. With WIF, claims are added as a property to these classes by using extensions to these interfaces (IClaimsIdentity and IClaimsPrincipal). IClaimsIdentity derives from IIdentity, and IClaimsPrincipal derives from IPrincipal. When the token is parsed, WIF automatically places the claims in an instance of these identity classes. Let’s begin by showing how to implement a custom token.
The first step is to create a class that represents the token:
public class YourCustomToken : SecurityToken
{
public List Claims { get; set; }
public XmlElement Signature { get; set; }
…
}
As you can see, your token needs to be a subclass of the SecurityToken class. This class will hold the information from the XML file (the token). In order for this token to be used in your application, you need to create a handler for it, which is derived from the SecurityTokenHandler class. This handler will be used to read and parse the XML file.
public class YourCustomTokenHandler : SecurityTokenHandler
{
…
public override SecurityToken ReadToken(XmlReader reader)
{
YourCustomToken token = new YourCustomToken(
Claims = from elem in XElement.Load(reader).Elements(Xname.Get(“Claim”, TokenNamespace)) select new Claim(elem.Attribute(“Namespace”).Value, elem.Value)
);
return token;
}
}
The handler also needs to override a method to validate the token, which will look something like to this:
public override ClaimsIdentityCollection ValidateToken(SecurityToken token)
{
ClaimsIdentityCollection claimsColl = new ClaimsIdentityCollection();
if (token is YourCustomToken)
{
IClaimsIdentity id = new ClaimsIdentity((token as YourCustomToken).Claims);
claimsColl.Add(id);
}
return claimsColl;
}
The above handler overrides methods that read and validate the token. The SecurityTokenHandler base class will automatically pass on this collection of claims to the ClaimsAuthenticationManager, and that class will in turn set the IClaimsPrincipal.Claims property to that collection. I left many of the details of these two classes, but I strongly suggest you familiarize yourself with them because there are other important methods that you must override.
Now you have access to the claims via code using the Thread.CurrentPrincipal or HttpContext.Current.User properties, just as you would with any other .NET application.
One of the important steps in this process is to register your handler in your configuration file. This configuration is an important one to remember:
<microsoft.identitymodel>
<service>
…
<securitytokenhandlers>
<add type="”YourCustomTokenHandler”">
</add></securitytokenhandlers>
</service>
</microsoft.identitymodel>
Summary
The above procedure gives you an idea of what WIF provides for you and how a token handler is implemented for your claims-based application. But what you really need to be aware of is that WIF provides out-of-the-box classes that already derive from SecurityTokenHandler, one for every standard token format (such as SAML, one of the more popular ones). Not all identity providers use the same format, but WIF provides many of the standard ones.
So, in the simplest cases, WIF’s defaults will do the work for you. All you need to do is to configure it in the configuration files. WIF provides an extensive configuration model far too complex to explain here, but a good starting point is this document: “Configuration for Windows Identity Foundation”. This configuration saves you from having to write code and should be clearly understood before writing a claims-based application. Hopefully, this introduction will have given you an initial understanding of how a WIF application would use claims-based identity.