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

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

问题描述

我将 Web Api 2.1 与 Asp.Net Identity 2 一起使用.我试图在我的 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.

我正在做的一些有助于诊断的事情:
我使用 only app.UseOAuthBearerTokens 作为 Asp.Net Identity 2 的身份验证.这意味着我删除了 app.UseCookieAuthentication(new CookieAuthenticationOptions()) 在您使用 Asp.Net Identity 2 创建新的 Web Api 2.1 项目时默认启用.

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 我正在注入我的存储库:

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() 上.

布洛克艾伦的这篇文章 很好地解释了为什么会这样.该方法有意将主体设置为 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天全站免登陆