Handling claims transformation in an OWIN middleware in .NET MVC part 1

Introduction

Claims have become widespread in software projects to tighten the security aspects of an application. We looked at claims before on this blog – see the link in the next paragraph – but time goes by and new features have been added to this technology lately. This is especially true as far as OWIN is concerned. In this mini-series we’ll concentrate on a very narrow aspect of claims in .NET MVC: claims transformation in OWIN middleware.

What are claims

We discussed claims on this blog in details starting here. Here comes a short summary to refresh your memory.

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. 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.

Here are some code examples of how a claim can be represented in C# code:

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");
}

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 then build a claims identity and a claims principal object as follows:

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

Later on in that series we saw how claims could be transformed. In this step the ClaimsPrincipal is transformed according to your needs. In a common web-based log-in scenario the only claim available may be the user name. If you need to check other claims during your authorisation process then you’ll need to ‘dress up’ the ClaimsPrincipal using some claims transformation technique.

It is also possible that the initial claims collection is too large. Then you may even have to remove the unnecessary claims before passing them on to your authorisation process. It is recommended to include only those claims that are absolutely necessary for your application – not more, not less.

In the original series we looked at how to transform claims in an MVC.NET application by registering the class responsible for the transformation in the web.config file. Now that we have OWIN we’ll see how claims transformation can be performed there instead.

What are OWIN and Katana?

We’ve taken up OWIN and Katana in various series on this blog lately so I won’t repeat that stuff here. Check out this page and scroll down to the “OWIN and Katana” section. In short Katana is a new light-weight web framework built by Microsoft. It is based on a specification called OWIN – Open Web Interface for .NET. The default MVC5 template in Visual Studio 2013 have elements of Katana and OWIN.

OWIN has been around for a while now so I guess you’ve come across it in your .NET development work. If not then check out one of the series available on this blog to get to learn the basics.

The demo project

Start Visual Studio 2013 and create a ASP.NET web application. It doesn’t matter what name you give to the project, I called mine “ClaimsTransformationInOwinDemo”. Select the MVC template in the “New ASP.NET Project” window. In the same window you’ll see that “Individual user accounts” is set as the default authentication mode. That’s fine, don’t change that. Then let VS create the project for you. The main OWIN-related security code will be stored in Startup.Auth.cs in the App_Start folder.

Locate HomeController in the Controllers folder. The Index method is very plain and simple:

public ActionResult Index()
{
	return View();
}

Let’s add some code before the return statement and see what we can find out about the user. Every controller has access to a property called User which represents of the user of the current thread. It is of type System.Security.Principal.IPrincipal and can be cast to a ClaimsPrincipal object which implements IPrincipal. ClaimsPrincipal is located in the System.Security.Claims namespace.

Let’s transform the Index method to the following:

public ActionResult Index()
{
	ClaimsPrincipal claimsPrincipal = User as ClaimsPrincipal;
	if (claimsPrincipal != null)
	{
		ClaimsIdentity claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
		Debug.WriteLine("User authenticated: {0}", claimsIdentity.IsAuthenticated);
		IEnumerable<Claim> claimsCollection = claimsPrincipal.Claims;
		foreach (Claim claim in claimsCollection)
		{
					
			Debug.WriteLine("Claim type: {0}, claim value type: {1}, claim value: {2}", claim.Type, claim.ValueType, claim.Value);
		}

	}
	return View();
}

So we case the User to a ClaimsPrincipal object. Then we read its identity and cast it to a ClaimsIdentity object which helps us decide whether the user is authenticated. Then we print the available claims to the Debug window. Running the HomeController with an unauthenticated user gives you some output similar to the following:

User authenticated: False
Claim type: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name, claim value type: http://www.w3.org/2001/XMLSchema#string, claim value:

IsAuthenticated yields “false” as expected. Then we see that we have one claim available by default and it’s the name claim. Its type is string – given by the claim type – and its value is an empty string, i.e. the user name is obviously unknown.

We’ll see investigate this more in the next post.

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.

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

Elliot Balynn's Blog

A directory of wonderful thoughts

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

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: