Web API 2 security extensibility points part 5: OWIN

Introduction

In the previous post we discussed how to add a custom authorisation filter to your .NET web application. We saw how you could derive from the AuthorizeAttribute class and implement your own logic for the IsAuthorized and HandleUnauthorizedRequest methods. The methods in the custom authorisation filter are called after any authentication filter is applied and before the appropriate controller action is executed.

In this post we’ll look at another entry point where you can apply your custom security logic in a .NET web application: OWIN

OWIN

We’ve discussed OWIN in 2 different series so far on this blog:

If you’re completely new to OWIN and Katana then you’re advised to skim through the introductory posts in those series. It’s pointless to regurgitate everything that’s been discussed again.

I’ll copy some relevant sections here to refresh your memory:

If you’re a .NET developer then you must have come across the new light-weight web framework standard called OWIN. Its implementation by Microsoft in .NET is called Katana. One primary goal of OWIN/Katana is to enable you to deploy the web-based project on a variety of hosts. Traditional ASP.NET applications were tied to IIS through the large System.Web library. It was impossible to develop a working enterprise web application without System.Web and IIS before OWIN/Katana came along. Now it’s perfectly feasible to host your application on other platforms.

Adding OWIN to CustomersApi

We’ve been working on a demo project called CustomersApi. We used the Web API 2 template in Visual Studio 2013. If you check the libraries and files created by the template there’s nothing about OWIN or Katana. I’m not sure why but the “normal” MVC template adds the OWIN-related libraries and some Katana middleware to your project along with the required Startup.cs file there’s nothing like that in the case of Web API.

That’s OK as it’s quite straightforward to add OWIN to our current project. In order to integrate the OWIN pipeline into our Web API application we’ll need to add the following NuGet packages. First off we need the OWIN version of the well-known System.Web library:

Install SystemWeb OWIN through NuGet

Second let’s add the following NuGet package which will let Web API and OWIN be connected:

Install Web API Owin through NuGet

The Startup class

The Startup class is the entry point into a Katana-based application. It’s like Global.asax in a traditional ASP.NET app. If you go through the posts on OWIN/Katana referenced above you’ll know that by convention this entry point class must be called “Startup” and not “StartUp” or “startup” i.e. the casing is important. Another convention is that the Startup class must contain a method called Configuration which accepts an object of type IAppBuilder.

Therefore add a class called Startup to the root of the project:

public class Startup
{
	public void Configuration(IAppBuilder appBuilder)
	{

	}
}

We already have Global.asax in our project but it’s OK to have a Startup and a Global.asax.cs file in the same project. You’ll get both if you create a project with the MVC template in Visual Studio 2013.

Let’s test if Configuration is being called at all. Add the following dummy code to the body of the Configuration method:

Debug.WriteLine("Within configuration...");

Start the project, navigate to the /customers endpoint and you should see that “Within configuration…” is indeed printed in the Debug window along with the other debug messages from the components we created before:

Within configuration…
Principal is authenticated at the start of SendAsync in CustomAuthenticationMessageHandler: False
Incoming principal in custom auth filter AuthenticateAsync method is authenticated: True
Incoming principal in custom auth filter ChallengeAsync method is authenticated: True
Principal is authenticated at the start of IsAuthorized in CustomAuthorizationFilterAttribute: True
Principal authenticated from extension method: True
Principal authenticated from shorthand property: True
Principal authenticated from User: True

This already gives you an indication of when an OWIN-based authentication logic will be carried out: it’s executed first in the security pipeline, i.e. even before the authentication filter is called.

Adding our own middleware

We’ll re-use the steps outlined in this post about the Application Function to add our own middleware. An OWIN middleware must follow a couple of conventions otherwise the App Builder will throw a runtime exception.

Add a new folder to the project called OwinMiddleware. Insert a class called SecurityComponent to that folder with the following stub:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using ApplicationFunction = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task>;

namespace CustomersApi.OwinMiddleware
{
	public class SecurityComponent
	{
		private readonly ApplicationFunction _nextComponent;

		public SecurityComponent(ApplicationFunction appFunc)
		{
			if (appFunc == null) throw new ArgumentNullException("AppFunc of next component");
			_nextComponent = appFunc;
		}

		public async Task Invoke(IDictionary<string, object> environment)
		{
			Debug.WriteLine("Running SecurityComponent...");
			await _nextComponent(environment);
		}
	}
}

The elements that an OWIN middleware must have by convention are the following:

  • A constructor that accepts an application function as seen above: a function that returns the OWIN environment dictionary and returns a Task
  • A public method called Invoke which accepts the environment dictionary

The above code fulfils both conditions so we can register it with the OWIN pipeline. It’s very simple. We tell the app builder object in the Configuration method to “use” it:

public void Configuration(IAppBuilder appBuilder)
{
	appBuilder.Use<SecurityComponent>();
}

Run the application now, navigate to /customers and you should see that the middleware is indeed invoked:

Running SecurityComponent…
Principal is authenticated at the start of SendAsync in CustomAuthenticationMessageHandler: False
Incoming principal in custom auth filter AuthenticateAsync method is authenticated: True
Incoming principal in custom auth filter ChallengeAsync method is authenticated: True
Principal is authenticated at the start of IsAuthorized in CustomAuthorizationFilterAttribute: True
Principal authenticated from extension method: True
Principal authenticated from shorthand property: True
Principal authenticated from User: True

Extracting the principal

So how do we get to the principal in the request? The “environment” parameter of the Invoke method includes a range of loosely typed objects by keys of type string. One of those is “server.user”:

public async Task Invoke(IDictionary<string, object> environment)
{
	if (environment.ContainsKey("server.User"))
	{
		IPrincipal principalAtOwinStart = environment["server.User"] as IPrincipal;
		Debug.WriteLine(string.Format("Principal is authenticated at the start of OWIN security middleware: {0}", principalAtOwinStart.Identity.IsAuthenticated));
	}
	await _nextComponent(environment);
}

Running the /customers endpoint will result in the following debug output:

Principal is authenticated at the start of OWIN security middleware: False
Principal is authenticated at the start of SendAsync in CustomAuthenticationMessageHandler: False
Incoming principal in custom auth filter AuthenticateAsync method is authenticated: True
Incoming principal in custom auth filter ChallengeAsync method is authenticated: True
Principal is authenticated at the start of IsAuthorized in CustomAuthorizationFilterAttribute: True
Principal authenticated from extension method: True
Principal authenticated from shorthand property: True
Principal authenticated from User: True

So the principal is obviously not yet authenticated.

Another way to get to the same result is to use the OwinContext wrapper object which provides a more type safe, i.e. user friendly way of extracting the user in the current thread:

public async Task Invoke(IDictionary<string, object> environment)
{	
	OwinContext owinContext = new OwinContext(environment);
	IPrincipal principalAtOwinStart = owinContext.Request.User;
	Debug.WriteLine(string.Format("Principal is authenticated at the start of OWIN security middleware: {0}", principalAtOwinStart.Identity.IsAuthenticated));
	await _nextComponent(environment);
}

You can easily set the current principal:

IPrincipal genericPrincipal = new GenericPrincipal(new GenericIdentity("Andras", "CustomIdentification"), new string[] { "Admin", "PowerUser" });
owinContext.Request.User = genericPrincipal;

Note the change of the debug messages. The principal in the HTTP request is then authenticated already when the authentication filter starts:

Principal is authenticated at the start of OWIN security middleware: False
Principal is authenticated at the start of SendAsync in CustomAuthenticationMessageHandler: True
Incoming principal in custom auth filter AuthenticateAsync method is authenticated: True
Incoming principal in custom auth filter ChallengeAsync method is authenticated: True
Principal is authenticated at the start of IsAuthorized in CustomAuthorizationFilterAttribute: True
Principal authenticated from extension method: True
Principal authenticated from shorthand property: True
Principal authenticated from User: True

That’s all about the basics of Web API security extensions. We’ll explore Web API security more thoroughly later on in upcoming series.

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

iReadable { }

.NET Tips & Tricks

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: