Host authentication and Web API with OWIN and active vs. passive authentication middleware
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.
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.
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.
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.