异步设置Thread.CurrentPrincipal?
使用ASP.NET WebAPI,在身份validation期间,设置Thread.CurrentPrincipal
,以便控制器稍后可以使用ApiController.User
属性。
如果该身份validation步骤变为异步(以咨询另一个系统),则会丢失CurrentPrincipal
任何突变(当调用者await
恢复同步上下文时)。
这是一个非常简化的示例(在实际代码中,身份validation发生在动作filter中):
using System.Diagnostics; using System.Security.Principal; using System.Threading; using System.Threading.Tasks; public class ExampleAsyncController : System.Web.Http.ApiController { public async Task GetAsync() { await AuthenticateAsync(); // The await above saved/restored the current synchronization // context, thus undoing the assignment in AuthenticateAsync(). Debug.Assert(User is GenericPrincipal); } private static async Task AuthenticateAsync() { // Save the current HttpContext because it's null after await. var currentHttpContext = System.Web.HttpContext.Current; // Asynchronously determine identity. await Task.Delay(1000); var identity = new GenericIdentity(""); var roles = new string[] { }; Thread.CurrentPrincipal = new GenericPrincipal(identity, roles); currentHttpContext.User = Thread.CurrentPrincipal; } }
如何在异步函数中设置Thread.CurrentPrincipal
,以便调用者的await
在恢复同步上下文时不会丢弃该突变?
您还必须设置HttpContext.Current.User
。 有关详细信息,请参阅此答案和此博客文章 。
更新:还要确保您在.NET 4.5上运行并将UserTaskFriendlySynchronizationContext
设置为true
。