【问题标题】:Web API ExceptionFilter doesn't have the Thread.CurrentPrincipal set in an AuthorizationFilterWeb API ExceptionFilter 没有在 AuthorizationFilter 中设置 Thread.CurrentPrincipal
【发布时间】:2014-04-17 20:36:41
【问题描述】:

在每个请求开始时,我将 AuthorizationFilter 中的 Thread.CurrentPrincipal 设置为具有自定义声明的经过身份验证的用户。当我尝试在 ExceptionFilter 中记录控制器操作中引发的错误时,从 ExceptionFilter 中访问的主体与我在 AuthorizationFilter 中设置的主体不同。事实上,我在 ExceptionFilter 中获得的主体是在我在 AuthorizationFilter 中更改它之前存在于线程上的主体。浏览 Web API 的源代码后,我想我发现了与任务执行上下文有关的问题(参见 ApiController 类,ExecuteAsync 方法)。下面的示例代码是重现问题的简单方法:

class Program
{
    static void Main(string[] args)
    {
        SetIdentity("originIdentity");

        Func<Task> controllerAction = () =>
        {
            Console.WriteLine("Identity is correct in controller: " + Thread.CurrentPrincipal.Identity.Name);

            return Task.FromResult("result");
        };

        Func<Task> authFilter = async () =>
        {
            SetIdentity("newIdentity");
            Console.WriteLine("Set identity to " + Thread.CurrentPrincipal.Identity.Name);

            await controllerAction();
        };

        Func<Task> exceptionFilter = async () =>
        {
            Console.WriteLine("Original identity: " + Thread.CurrentPrincipal.Identity.Name);

            //there would be a try block around this so we can catch exceptions
            await authFilter();

            Console.WriteLine("Identity is what it was before: " + Thread.CurrentPrincipal.Identity.Name);
        };

        exceptionFilter().Wait();

        Console.Read();
    }

    private static void SetIdentity(string originidentity)
    {
        var originIdentity = new ClaimsIdentity("HeaderAuthentication");
        originIdentity.AddClaim(new Claim(ClaimTypes.Name, originidentity));
        Thread.CurrentPrincipal = new ClaimsPrincipal(originIdentity);
    }
}

然后输出:

Original identity: originIdentity
Set identity to newIdentity
Identity is correct in controller: newIdentity
Identity is what it was before: originIdentity

我的问题是:

  1. 我看到的是我认为我看到的吗?
  2. 这是一个错误还是 Web API 中的设计? TPL 以这种方式运行是有道理的,但很难想象这是 Web API 中的预期行为
  3. 在 Web API 中解决此问题的推荐/干净方法是什么?

【问题讨论】:

    标签: logging exception-handling asp.net-web-api task-parallel-library


    【解决方案1】:

    Thread.CurrentPrincipal 在某些线程/并行情况下存在一些问题。

    这就是 Web API v2 不再使用它的原因。使用 HttpRequestMessage 上的 GetRequestContext() 扩展方法来获取当前用户/或设置它

    【讨论】:

      猜你喜欢
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 2019-06-15
      • 2015-09-29
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      • 2015-12-24
      相关资源
      最近更新 更多