我已经实现了一个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);
});
}
答案 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,如图所示。