Introduction to Claims based security in .NET4.5 with C# Part 1: the absolute basics

The well-known built-in Identity objects, such as GenericPrincipal and WindowsPrincipal have been available for more than 10 years now in .NET. Claims were introduced in .NET4.5 to build Claims based authentication into the framework in the form of ClaimsIdentity and ClaimsPrincipal in the System.Security.Claims namespace.

Before we see some action in terms of code let’s look at a general description of claims. If you already know what they are and want to see the code then you can safely jump this section.

What is a claim?

A claim in the world of authentication and authorisation can be defined as a statement about an entity, typically a user. A claim can be very fine grained:

  • Tom is an administrator
  • Tom’s email address is tom@yahoo.com
  • Tom lives in Los Angeles
  • Tom’s allowed to view sales figures between 2009 and 2012
  • Tom’s allowed to wipe out the universe

If you are familiar with Roles in the ASP.NET Membership framework then you’ll see that Roles are also claim types. Claims come in key-value pairs:

  • Role: administrator
  • Email: tom@yahoo.com
  • Address: Los Angeles
  • Viewable sales period: 2009-2012

These statements are a lot more expressive than just putting a user in a specific role, such as marketing, sales, IT etc. If you want to create a more fine-grained authorisation process then you’ll need to create specialised roles, like the inevitable SuperAdmin and the just as inevitable SuperSuperAdmin.

Claims originate from a trusted entity other than the one that is being described. This means that it is not enough that Tom says that he is an administrator. If your company’s intranet runs on Windows then Tom will most likely figure in Active Directory/Email server/Sales authorisation system and it will be these systems that will hold these claims about Tom. The idea is that if a trusted entity such as AD tells us things about Tom then we believe them a lot more than if Tom himself comes with the same claims. This external trusted entity is called an Issuer. The KEY in the key-value pairs is called a Type and the VALUE in the key-value pair is called the Value. Example:

  • Type: role
  • Value: marketing
  • Issuer: Active Directory

Trust is very important: normally we trust AD and our own Exchange Server, but it might not be as straightforward with other external systems. In such cases there must be something else, e.g. a certificate that authenticates the issuer.

An advantage of claims is that they can be handled by disparate authentication systems which can have different implementations of claims: groups, roles, permissions, capabilities etc. If two such systems need to communicate through authorisation data then Claims will be a good common ground to start with.

How do we attach these claims to the Principals?

A Claim is represented in .NET4.5 by an object called… …Claim! It is found in the System.Security.Claims namespace.

There is a new implementation of the well-known IIdentity interface called ClaimsIdentity. This implementation holds an IEnumerable of Claim objects. This means that this type of identity is described by an arbitrary number of statements.

Not surprisingly we also have a new implementation of IPrincipal called ClaimsPrincipal which holds a read-only collection of ClaimsIdentity objects. Normally this collection of identities will only hold one ClaimsIdentity element. In some special scenarios with disparate systems a user can have different types of identities if they can identify themselves in multiple ways. The ClaimsPrincipal implementation accommodates this eventuality.

The advantage with having these new objects deriving from IPrincipal and IIdentity is compatibility. You can start introducing Claims in your project where you work with IPrincipals and IIdentities without breaking your code.

It’s been enough talk, let’s see some action

Start Visual Studio 2012 and create a new Console application with .NET4.5 as the underlying framework.

The simplest way to create a new Claim is by providing a Type and a Value in the Claim constructor:

static void Main(string[] args)
        {
            Claim claim = new Claim("Name", "Andras");
        }

You can use strings to describe types as above but we all know the disadvantages with such hard-coded strings. There is an enumeration called ClaimTypes that stores the most common claim types.

static void Main(string[] args)
        {
            Claim claim = new Claim("Name", "Andras");
            Claim newClaim = new Claim(ClaimTypes.Country, "Sweden");
        }

You can check out the values available in ClaimTypes using IntelliSense. It is safer to use the enumeration where-ever possible rather than the straight string values as chances are the system you’re trying to communicate Claims with will also understand the values behind the enumerated one. If you don’t find any suitable one there you can revert back to string-based Types and even define a formal namespace to the claim as follows:

new Claim("http://www.mycompany.com/building/floor", "Two")

Place the cursor on “Country” in ‘new Claim(ClaimTypes.Country, “Sweden”);’ and press F12. You’ll see a long list of namespaces, such as the following:

public const string Country = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country";

These namespaces will uniquely describe the claim type.

It is very rare that there’s only one claim about a person. Instead, claims come in collections, so let’s create one:

static void Main(string[] args)
        {
            IList<Claim> claimCollection = new List<Claim>
            {
                new Claim(ClaimTypes.Name, "Andras")
                , new Claim(ClaimTypes.Country, "Sweden")
                , new Claim(ClaimTypes.Gender, "M")
                , new Claim(ClaimTypes.Surname, "Nemes")
                , new Claim(ClaimTypes.Email, "hello@me.com")
                , new Claim(ClaimTypes.Role, "IT")
            };
        }

We can easily build an object of type IIDentity out of a collection of claims, in this case a ClaimsIdentity as mentioned above:

ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimCollection);

We now test if this identity is authenticated or not:

Console.WriteLine(claimsIdentity.IsAuthenticated);

Run the Console app and test for yourself; IsAuthenticated will return false. Claims can be attached to anonymous users which is different from the standard principal types in .NET4 and earlier. It used to be enough for the user to have a name for them to be authenticated. With Claims that is not enough. Why would you attach claims to an unauthenticated user? It is possible that you gather information about a user on your site which will be used to save their preferences when they are turned into members of your site.

If you want to turn this IIdentity into an authenticated one you need to provide the authentication type which is a string descriptor:

ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimCollection, "My e-commerce website");

Run the application again and you’ll see that the user is now authenticated.

Using our identity object we can also create an IPrincipal:

ClaimsPrincipal principal = new ClaimsPrincipal(claimsIdentity);

As ClaimsPrincipal implements IPrincipal we can assign the ClaimsPrincipal to the current Thread as the current principal:

Thread.CurrentPrincipal = principal;

From this point on the principal is available on the current thread in the rest of the application.

Create a new method called Setup() and copy over all our code as follows:

static void Main(string[] args)
        {
            Setup();

            Console.ReadLine();
        }

        private static void Setup()
        {
            IList<Claim> claimCollection = new List<Claim>
            {
                new Claim(ClaimTypes.Name, "Andras")
                , new Claim(ClaimTypes.Country, "Sweden")
                , new Claim(ClaimTypes.Gender, "M")
                , new Claim(ClaimTypes.Surname, "Nemes")
                , new Claim(ClaimTypes.Email, "hello@me.com")
                , new Claim(ClaimTypes.Role, "IT")
            };

            ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimCollection, "My e-commerce website");

            Console.WriteLine(claimsIdentity.IsAuthenticated);

            ClaimsPrincipal principal = new ClaimsPrincipal(claimsIdentity);
            Thread.CurrentPrincipal = principal;
        }

Let’s see if the new Claims-related objects can be used in .NET4 where Claims are not available. Create a new method as follows:

private static void CheckCompatibility()
        {

        }

Call this method from Main as follows:

static void Main(string[] args)
        {
            Setup();
            CheckCompatibility();

            Console.ReadLine();
        }

Add the following to the CheckCompatibility method:

IPrincipal currentPrincipal = Thread.CurrentPrincipal;
Console.WriteLine(currentPrincipal.Identity.Name);

Run the application and the name you entered in the claims collection will be shown on the output window. The call for the Name property will look through the claims in the ClaimsIdentity object and extracts the value of Name claim type.

In some cases it is not straightforward what a ‘Name’ type means. Is it the unique identifier of the user? Is it the email address? Or is it the display name? You can easily specify how a claim type is defined. You can pass two extra values to the ClaimsIdentity constructor: which claim type constitutes the ‘Name’ and the ‘Role’ claim types. So if you want the email address to be the ‘Name’ claim type you would do as follows:

ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimCollection, "My e-commerce website", ClaimTypes.Email, ClaimTypes.Role);

Run the application and you will see that the email is returned as the name from the claim collection.

You can check if a user is in a specific role as before:

private static void CheckCompatibility()
        {
            IPrincipal currentPrincipal = Thread.CurrentPrincipal;
            Console.WriteLine(currentPrincipal.Identity.Name);
            Console.WriteLine(currentPrincipal.IsInRole("IT"));
        }

…which will yield true.

So we now know that ‘old’ authentication code will still be able to handle the Claims implementation. We’ll now turn to ‘new’ code. Create a new method called CheckNewClaimsUsage() and call it from Main just after CheckCompatibility().
The following will retrieve the current claims principal from the current thread:

private static void CheckNewClaimsUsage()
        {
            ClaimsPrincipal currentClaimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
        }

Now you’ll have access to all the extra methods and properties built into ClaimsPrincipal. You can enumerate through the claims collection in the principal object, find a specific claim using Linq etc. Example:

private static void CheckNewClaimsUsage()
        {
            ClaimsPrincipal currentClaimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
            Claim nameClaim = currentClaimsPrincipal.FindFirst(ClaimTypes.Name);
            Console.WriteLine(nameClaim.Value);
        }

You can use .HasClaim to check if the claims collection includes a specific claim you’re looking for.

You can also query the identities of the ClaimsPrincipal:

foreach (ClaimsIdentity ci in currentClaimsPrincipal.Identities)
            {
                Console.WriteLine(ci.Name);
            }

The line…

ClaimsPrincipal currentClaimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;

…becomes so common that there’s a built-in way to achieve the same thing:

ClaimsPrincipal currentClaimsPrincipal = ClaimsPrincipal.Current;

This will throw an exception if the concrete IPrincipal type is not ClaimsPrincipal for whatever reason.

We have looked at the very basics of Claims in .NET4.5. The next post will look at the new IIdentity and IPrincipal inheritance model.

You can view the list of posts on Security and Cryptography here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

27 Responses to Introduction to Claims based security in .NET4.5 with C# Part 1: the absolute basics

  1. Stefan Karlsson says:

    Thank you for a well done tutorial,
    It really helped me understand claims more.

  2. Mathias says:

    Thank you for this Tutorial. It helped me too to understand more what a claim is. I will now look for your other Tuts aout claims. Trying to this stuff.

  3. anandkp says:

    Thank you so much for a very well written tutorial

  4. Pingback: Introduction to Claims based security in .NET4.5 with C# Part 1: the absolute basics | Manuscript Collection

  5. vcardinsctor Cardins says:

    Finally I did understand the whole process. Thanks for the making it so clear and didactic !!

  6. Josh says:

    Just wanted to thank you for putting this series together. It was just what I was looking for.

  7. happy koder says:

    A big thank you my friend. This whole series is super useful to all newbies to Claims based authentication. Keep up the good work.

  8. Sepehr says:

    Such a nice and easy to understand article. Thank you mate very much!

  9. Ray says:

    Very nice and easy to understand. Love it!!

  10. While this looks like a lot of great information, there is a huge assumption of prior knowledge required to understand it (i.e. IPrincipal and IIdentity, what are they and how do they work? Why does adding a string to the ClaimsIdentity definition suddenly make it authenticate? etc.) The title Absolute Basics is a bit misleading. I will have to come back after catching up on those

  11. M Ali says:

    Very nice and easy to understand. Love it good time

  12. Pingback: Explaining the code behind authenticating MVC5 app with Azure AD | Robert Daniel Moore's Blog

  13. Pingback: Authentication and Authorization | Sticky Notes

  14. M V Sravan kumar says:

    Hi Andras Nemes,

    The explanation of new implementation of ClaimsIdentity and ClaimsPrincipal from IIdentity and IPrincipal is awesome.

    Very nice and easy to understand

  15. towkneed says:

    Just started but looks absolutely wonderful so far.

    I’m primarily a SharePoint Developer/Admin/Architect (although I’ve done – and do – a lot of other stuff over the years) whose been taxes with exploring two factor authentication via a product called “Duo”. I realize I’m going to have right a custom STS/SAML auth provider and I’ve been looking for something that starts off with the basics and goes up. I may have found it. It’s Friday at 5 now and I’ll be coming back here Monday.

  16. Yong Hur says:

    Your code worked! Thanks for the valuable tip.
    private static void CheckCompatibility()
    {
    IPrincipal currentPrincipal = Thread.CurrentPrincipal;
    Console.WriteLine(currentPrincipal.Identity.Name);
    Console.WriteLine(currentPrincipal.IsInRole(“IT”));
    }

  17. Parth Mistry says:

    Hello Andras ,

    It would be nice if link up all your series posts with previous(exists in top) and next post links (add in footer of post).

  18. Pingback: Custom Claims-based Windows Authentication in ASP.net MVC 5 « My Tech Notes My Tech Notes

  19. Pingback: Confluence: Unity

  20. Mario Dejo says:

    Amazing Tutorial!!! Congrats!!

  21. Thank you for an very well explained article.

  22. Congratulations for the very well written article!

  23. Raj Mittal says:

    Very precise and concise. Thanks. even wiki is confusing about claims

  24. Rajalakshmi says:

    I am from india, Very thankful to you

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Ricos Blog zu Softwaredesign- und architektur

Ideen und Gedanken rund um Softwaredesign und -architektur, Domain-Driven Design, C# und Windows Azure

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: