User (IPrincipal) not available on ApiController's constructor using Web Api 2.1 and Owin

asp.net-identity-2, asp.net-web-api2, c#, katana, owin

Solution

The problem lies indeed with `config.SuppressDefaultHostAuthentication()`.

This article by Brock Allen nicely explains why that is. The method sets the principal intentionally to null so that default authentication like cookies do not work. Instead, the Web API Authentication filter then takes care of the authentication part.

Removing this configuration when you do not have cookie authentication could be an option.

A neat solution as mentioned here, is to scope the Web API parts of the application, so that you can separate out this configuration to a specific path only:

public void Configuration(IAppBuilder app)
{
    var configuration = WebApiConfiguration.HttpConfiguration;
    app.Map("/api", inner =>
    {
        inner.SuppressDefaultHostAuthentication();
        // ...
        inner.UseWebApi(configuration);
    });
}

Problem

I am Using Web Api 2.1 with Asp.Net Identity 2. I am trying to get the authenticated User on my ApiController's constructor (I am using AutoFac to inject my dependencies), but the User shows as not authenticated when the constructor is called. I am trying to get the User so I can generate Audit information for any DB write-operations. A few things I'm doing that can help on the diagnosis: I am using only `app.UseOAuthBearerTokens` as authentication with Asp.Net Identity 2. This means that I removed the `app.UseCookieAuthentication(new CookieAuthenticationOptions())` that comes enabled by default when you are creating a new Web Api 2.1 project with Asp.Net Identity 2. Inside `WebApiConfig` I'm injecting my repository: ``` builder.RegisterType<ValueRepository>().As<IValueRepository>().InstancePerRequest(); ``` Here's my controller: ``` [RoutePrefix("api/values")] public class ValuesController : ApiController { private IValueRepository valueRepository; public ValuesController(IValueRepository repo) { valueRepository = repo; // I would need the User information here to pass it to my repository // something like this: valueRepository.SetUser(User); } protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext) { base.Initialize(controllerContext); // User is not avaliable here either... } } ``` But if I inspect the User object on the constructor, this is what I get: The authentication is working, if I don't pass my token, it will respond with `Unauthorized`. If I pass the token and I try to access the user from any of the methods, it is authenticated and populated correctly. It just doesn't show up on the constructor when it is called. In my `WebApiConfig` I am using: ``` public static void Register(HttpConfiguration config) { config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // ... other unrelated injections using AutoFac } ``` I noticed that if I remove this line: `config.SuppressDefaultHostAuthentication()` the User is populated on the constructor. Is this expected? How can I get the authenticated user on the constructor? EDIT: As Rikard suggested I tried to get the user in the Initialize method, but it is still not available, giving me the same thing described in the image.

Original source

Related problems