WebApi:User.Identity.IsAuthenticated为第一个请求为true,之后为false

时间:2013-06-13 14:08:02

标签: .net asp.net-web-api http-basic-authentication

我已经实现了一个Web API。

<authentication mode="None" />

我正在使用基本授权,并在AuthorizeAttribute中设置Thread.CurrentPrincipal。

第一次启动/调试应用程序后,我提交请求,设置Thread.CurrentPrincipal(IsAuthenticated = true)服务器端,IsAuthenticated在我的控制器中返回true,如预期的那样。但是,此后的任何请求都将Thread.CurrentPrincipal设置为正常,但是随着执行时间到达我的控制器方法,控制器的User.Identity属性已更改,并且IsAuthenticated = false。

我无法在启动应用程序后第一次弄清楚为什么IsAuthenticated = true?!它应该是每一次,因为我手动设置Thread.CurrentPrinciple,但在那之间和命中我的控制器之间,它正在被替换!

更新

这与我添加的MediaTypeFormatter有关。当我删除格式化程序时,我没有遇到问题。执行格式化程序的代码如下:

public override Task<object> ReadFromStreamAsync(Type type, System.IO.Stream webStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
    {
        return Task.Factory.StartNew(() =>
        {
            string temporaryFilePath = Path.Combine(TemporaryDirectory, Path.GetRandomFileName());

            using (FileStream fileStream = new FileStream(temporaryFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
            {
                webStream.CopyTo(fileStream);
            }

            return (object)new CustomFile(temporaryFilePath);
        });
    }

1 个答案:

答案 0 :(得分:2)

答案将详细解释here

简而言之,设置Thread.CurrentPrincipal是不够的。我现在也设置了HttpContext.Current.User,它正在工作。

在原帖中,正在调用MediaTypeFormatter上的异步方法,创建其他线程,导致CurrentPrinciple附加到其他某个线程,而不是您的控制器操作最终被执行的线程。

至于为什么必须在两个地方设置,可以找到解释here。它说:

  

如果您的应用程序执行任何自定义身份验证逻辑,您必须   在两个地方设置校长:

     

Thread.CurrentPrincipal:此属性是设置的标准方法   线程在.NET中的主体。 HttpContext.Current.User:这个属性是   特定于ASP.NET。

     

以下代码显示了如何设置   负责人:

private void SetPrincipal(IPrincipal principal)
{
    Thread.CurrentPrincipal = principal;
    if (HttpContext.Current != null)
    {
        HttpContext.Current.User = principal;
    }
}
     

对于网络托管,您必须在两个地方设置主体;除此以外   安全上下文可能会变得不一致。对于自托管,   但是,HttpContext.Current为null。确保您的代码   因此,host-agnostic在分配之前检查null   HttpContext.Current,如图所示。