在每个请求开始时,我将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
我的问题是:
答案 0 :(得分:4)
Thread.CurrentPrincipal在某些线程/并行情况下存在一些问题。
这就是它在Web API v2中不再使用的原因。在HttpRequestMessage上使用GetRequestContext()扩展方法来获取当前用户/或设置它