用户(IPrincipal)在使用Web Api 2.1和Owin的ApiController的构造函数上不可用 [英] User (IPrincipal) not available on ApiController's constructor using Web Api 2.1 and Owin

查看:264
本文介绍了用户(IPrincipal)在使用Web Api 2.1和Owin的ApiController的构造函数上不可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有Asp.Net Identity 2的Web Api 2.1.我试图在ApiController的构造函数上获取经过身份验证的用户(我正在使用AutoFac注入依赖项),但是当构造函数为叫.

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.

我正在做的一些事情可以帮助诊断:
我仅将 app.UseOAuthBearerTokens用作Asp.Net Identity 2的身份验证.这意味着在创建新的Web Api 2.1项目时,我删除了默认情况下启用的app.UseCookieAuthentication(new CookieAuthenticationOptions()).使用Asp.Net Identity 2.

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.

WebApiConfig内部,我正在注入存储库:

Inside WebApiConfig I'm injecting my repository:

builder.RegisterType<ValueRepository>().As<IValueRepository>().InstancePerRequest();

这是我的控制器:

[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...
    }
}

但是,如果我检查构造函数上的User对象,这就是我得到的:

But if I inspect the User object on the constructor, this is what I get:

身份验证有效,如果我不传递令牌,它将以Unauthorized响应.如果我传递令牌,并且尝试通过任何方法访问用户,则该令牌将经过身份验证并正确填充.调用时,它只是不会显示在构造函数上.

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.

在我的WebApiConfig中,我正在使用:

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
 } 

我注意到,如果我删除以下行:config.SuppressDefaultHostAuthentication()用户将填充到构造函数中.

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?

正如Rikard所建议的那样,我尝试让用户使用Initialize方法,但该方法仍然不可用,给了我与图像中描述的相同的东西.

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.

推荐答案

问题确实出在config.SuppressDefaultHostAuthentication()上.

Brock Allen的这篇文章很好地解释了为什么会这样.该方法有意将主体设置为null,以使默认身份验证(例如cookie)不起作用.而是使用 Web API身份验证过滤器来解决验证部分的内容.

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.

当您没有Cookie身份验证时,可以删除此配置.

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

一种简洁的解决方案如此处所述,其作用是确定应用程序的Web API部分的范围,以便您可以分离将此配置仅分配到特定路径:

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);
    });
}

这篇关于用户(IPrincipal)在使用Web Api 2.1和Owin的ApiController的构造函数上不可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆