Skip to content

Host authentication and Web API with OWIN and active vs. passive authentication middleware

October 27, 2013

A quick note about Web API 2 security running in OWIN and a ASP.NET project (which you will see with the new templates in Visual Studio 2013). By default, Web API code running in a host will inherit the host’s authentication model. This means if the web application uses cookie authentication or windows authentication for the HTML portion of the application, then when Ajax calls are made from these web pages back to the server this same authentication will be passed along to calls into Web API.

RequestContext.Principal

Before I even get into the main part of this post, a side note on the identity of the calling user: Web API 2 introduced a new RequestContext class that contains a Principal property. This is now the proper location to look for the identity of the caller. This replaces the prior mechanisms of Thread.CurrentPrincipal and/or HttpContext.User. This is also what you would assign to if you are writing code to authenticate the caller in Web API.

SuppressDefaultHostAuthentication

While the MVC templates use a cookie based authentication mechanism, the new SPA templates prefer to use a token based authentication model explicitly passed via the Authorization HTTP header (which is better since it avoids CSRF attacks). This means that the default authentication from the host must be ignored since the authentication will be performed against something else other than a cookie. Web API 2 added a feature to ignore the host level authentication called SuppressDefaultHostAuthentication. This is an extension method on the HttpConfiguration that adds a message handler. The purpose of this message handler is to simply (and explicitly) assign an anonymous principal to the RequestContext’s Principal property. This way if cookie middleware does process an incoming cookie, by the time the call arrives at Web API the caller will be treated as anonymous.

Authentication filters

So then how will Web API code authenticate the caller? Well, in Web API 2 a new filter was added: AuthenticationFilter. This is a dedicated stage in the Web API pipeline for inspecting and authenticating the HTTP request. You can write your own, or you can use the new built-in HostAuthenticationFilter. The name of this new authentication filter sounds like a misnomer — we just suppressed the host authentication with with the SuppressDefaultHostAuthentication extension method — why are we now trying to authenticate form the host? Well, the HostAuthenticationFilter accepts a constructor parameter indicating which type of authentication we will use from the host. In the SPA templates they use one called “Bearer” (which is different than cookie).

The reason Web API is deferring back out to the host is because of the move to OWIN authentication middleware. OWIN authentication middleware is providing a generic and host independent framework for authentication. This same OWIN authentication middleware could also be used to authenticate calls into SignalR or Nancy. This makes more sense than Web API building their own custom authentication framework that would only work in Web API.

Active vs Passive authentication middleware

One question that arises — if the new templates have multiple OWIN authentication middleware configured, then which one is really used? Well, OWIN authentication middleware has the concept of passive vs. active. Active middleware always look at every incoming request and attempt to authenticate the call and if successful they create a principal that represents the current user and assign that principal to the hosting environment. Passive middleware, on the other hand, only inspects the request when asked to. In the case of the default templates from Visual Studio 2013, all the middleware configured are all passive by default, except for the “main” cookie authentication middleware (turns out there are two cookie middlewares that get used in some templates — the main one and another one for external identity providers and this other one is marked as passive).

All together now

So then in Web API when you use the HostAuthenticationFilter, you’re normally using it with a passive OWIN authentication middleware. When the authentication filter runs, it explicitly asks the OWIN authentication middleware to run and determine the identity of the caller. If successful, the result is populated into the RequestContext.Principal.

HTH

7 Comments leave one →
  1. October 28, 2013 2:20 pm

    >>use a token based authentication model passed via the Authorization HTTP header (which is better since it avoids CSRF attacks

    AFAIK, this is not correct. Authorization Header is vulnerable to CSRF attack, http://www.asp.net/web-api/overview/security/basic-authentication

    • October 28, 2013 8:08 pm

      What is vulnerable is implicit passing by the browser. This is true for cookie and basic auth and windows auth — any time the browser implicitly passes credentials, CSRF is an issue. When writing JS and explicitly passing an authorization header this is not an issue. It is certainly subtle.

    • October 29, 2013 6:18 pm

      Updated to “explicitly passed via the Authorization header” for clarification. :)

  2. Andy permalink
    November 8, 2013 1:16 pm

    Where can I find a simple example of what you just described here? I don’t want to use an external authn provider, I’m happy to roll my own, but can’t find a simple example using Owin/Katana. Even Katana doesn’t have a sample of this (or much of anything else, for that matter ;) ).

    • November 10, 2013 12:03 pm

      Are the templates in VS2013 not sufficient? I don’t have any samples of my own to share, so sorry.

Trackbacks

  1. Dissecting the Web API Individual Accounts Template–Part 2: Local Accounts | www.leastprivilege.com
  2. A primer on external login providers (social logins) with OWIN/Katana authentication middleware | brockallen

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

%d bloggers like this: