Wiring up a custom authentication method with OWIN in Web API Part 4: putting the components to work

Introduction

In the previous post we built two important components around the custom authentication logic. First off, we wrote a very simple implementation of the abstract AuthenticationOptions class where we only declared the name of the authentication mode. You can anyway add any extra property and overloaded constructors as you wish to this class. Then we built the custom authentication handler, i.e. PinAuthenticationHandler which derives from the abstract AuthenticationHandler class.

In this post we’ll add a couple more components specifically to add our authentication handler to the OWIN chain. We’ll also test the authentication logic.

The authentication middleware

In order to be able to follow this post you should have at least some basic knowledge of OWIN and Katana components: how they are written, what conventions they follow and how they are added to the OWIN middleware chain. As noted before, there are sources on this blog, e.g. here, that goes through OWIN from the ground up.

Authentication middleware in OWIN has a specially designed base class: AuthenticationMiddleware. It is a base class for all types of OWIN authentication middleware and has a large number of built-in implementations, e.g. CookieAuthenticationMiddleware, GoogleAuthenticationMiddleware or WsFederationAuthenticationMiddleware. AuthenticationMiddleware is a generic class with a type parameter of type AuthenticationOptions just like we saw in the case of AuthenticationHandler. We already have an implementation of AuthenticationOptions so we’ll use that of course.

AuthenticationMiddleware has two requirements for the implementing classes:

  • Override the CreateHandler method which returns an AuthenticationHandler class
  • Have a constructor which at least has two parameters: one of type OwinMiddleware and another of type AuthenticationOptions

Our implementation of CreateHandler will be very simple: we’ll just return an instance of PinAuthenticationHandler. However, what is this OwinMiddleware class? OwinMiddleware is an abstract base class for all sorts of Owin middleware. If you’ve seen examples of other Owin middleware you’ll be aware of the “next” component. In OWIN the components are chained in some order and each component will call the “next” component in line when it is done with its logic, like in this example:

private readonly ApplicationFunction _nextComponent;

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

public async Task Invoke(IDictionary<string, object> environment)
{
    await _nextComponent(environment);
}

Add a class called PinBasedAuthMiddleware into the Authentication folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Owin;
using Microsoft.Owin.Security.Infrastructure;

namespace CustomAuthenticationOwin.Authentication
{
	public class PinBasedAuthMiddleware : AuthenticationMiddleware<PinBasedAuthenticationOptions>
	{
		public PinBasedAuthMiddleware(OwinMiddleware nextMiddleware, PinBasedAuthenticationOptions authOptions) 
			: base(nextMiddleware, authOptions)
		{}

		protected override AuthenticationHandler<PinBasedAuthenticationOptions> CreateHandler()
		{
			return new PinAuthenticationHandler();
		}
	}
}

You can see that it’s a very simple implementation with really not much “value added”.

The last class we need to write is the application function extension. Add a class called PinAuthenticationExtension into the Authentication folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CustomAuthenticationOwin.Authentication;

namespace Owin
{
	public static class PinAuthenticationExtension
	{
		public static void UsePinBasedAuthentication(this IAppBuilder appBuilder)
		{
			appBuilder.Use<PinBasedAuthMiddleware>(new PinBasedAuthenticationOptions());
		}
	}
}

This is very little code but it’s worth going through some important aspects of it.

This is of course an extension method that adds functionality to IAppBuilder. We’ll be able to call appBuilder.UsePinBasedAuthentication() from Startup.cs later on which follows OWIN conventions. Other developers may be looking for a similar “Use…” extension method when they type “appBuilder.” within the Configuration method in Startup.cs.

Note that the namespace is set to OWIN so that IntelliSense can easily pick up the extension method in Startup.cs which has a “using Owin” statement.

We then tell appBuilder to use our authentication middleware PinBasedAuthMiddleware. This overloaded Use method accepts an object param which will be used to inject into the constructor of PinBasedAuthMiddleware. We’ve seen above that PinBasedAuthMiddleware requires two elements in its constructor: OwinMiddleware and PinBasedAuthenticationOptions. We have PinBasedAuthenticationOptions for the second argument but what happened to OwinMiddleware? We don’t actually need to worry about it. Every OWIN middleware has to have a constructor with the “next” parameter, e.g. the one we saw above:

public WelcomeComponent(ApplicationFunction appFunc)

That is a must and .NET will complain if it’s not present. .NET will also take care of inserting the next component for you in the constructor at runtime. OwinMiddleware is just another form of the “next” component and PinBasedAuthMiddleware is an OWIN component just like WelcomeComponent.

We’ll carry out an experiment later on in this regard.

Startup

Here’s the revised Startup class:

public class Startup
{
	public void Configuration(IAppBuilder appBuilder)
	{
		appBuilder.UsePinBasedAuthentication();
	}
}

Testing

If you start the web application now and navigate to /customers you should get a 401:

Authorization has been denied for this request.

The reason is that the headers do not have an x-company-auth type so CustomersController is never executed. You can now run the authentication tester console application a couple of times and watch the output in the debug window. If the generated PIN is less than 500000 then you should see the following message:

{“Message”:”Authorization has been denied for this request.”}

Otherwise you should get the list of customers since the request is authenticated:

Response status code: OK
[{“Name”:”Nice customer”,”Address”:”USA”,”Telephone”:”123345456″},{“Name”:”Good customer”,”Address”:”UK”,”Telephone”:”9878757654″},{“Name”:”Awesome customer”,”Address”:”France”,”Telephone”:”34546456″}]

Great, we have successfully created a custom authentication middleware and wired it up with OWIN.

Middleware constructor parameters

To finish off this post let’s just perform an experiment. In PinAuthenticationExtension.cs modify UsePinBasedAuthentication as follows:

public static class PinAuthenticationExtension
{
	public static void UsePinBasedAuthentication(this IAppBuilder appBuilder)
	{
		appBuilder.Use<PinBasedAuthMiddleware>();
	}
}

Start the application and you’ll get an exception:

The class ‘CustomAuthenticationOwin.Authentication.PinBasedAuthMiddleware’ does not have a constructor taking 1 arguments.

That “1 argument” refers to the “next” component in the OWIN chain. The PinBasedAuthMiddleware constructor has 2 arguments so the error message is correct.

Modify UsePinBasedAuthentication to what it was before. Next let’s see what happens if we extend the constructor of PinBasedAuthMiddleware with a dummy boolean parameter:

public PinBasedAuthMiddleware(OwinMiddleware nextMiddleware, PinBasedAuthenticationOptions authOptions, bool testParam) 
			: base(nextMiddleware, authOptions)
{}

Now you’ll get the same error but this time .NET is looking for 2 arguments:

The class ‘CustomAuthenticationOwin.Authentication.PinBasedAuthMiddleware’ does not have a constructor taking 2 arguments.

Therefore the Use extension method if IAppBuilder can accept an arbitrary number of parameters in its object param array and .NET will try to match them against the constructor parameters of the implemented middleare OVER AND ABOVE the “next” parameter. The below call will pass in “true” for the “testParam” parameter:

public static void UsePinBasedAuthentication(this IAppBuilder appBuilder)
{
	appBuilder.Use<PinBasedAuthMiddleware>(new PinBasedAuthenticationOptions(), true);
}

This was only to demonstrate how to pass in extra arguments to an OWIN middleware. You can remove the boolean parameters from this experiment code if you wish.

In the next post, which finished this series, we’ll look into making our middleware more flexible. Currently the IsAuthorised method is tightly coupled with the “pin >= 500000” authentication logic. We want to be able to inject another implementation from the caller.

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: