Set Thread.CurrentPrincipal Asynchronously?
asp.net-web-api, async-await, c#
Solution
You have to set `HttpContext.Current.User` as well. See this answer and this blog post for more info.
Update: Also ensure you are running on .NET 4.5 and have `UserTaskFriendlySynchronizationContext` set to `true`.
Problem
Using ASP.NET WebAPI, during authentication, `Thread.CurrentPrincipal` is set so that controllers can later use the `ApiController.User` property. If that authentication step becomes asynchronous (to consult another system), any mutation of `CurrentPrincipal` is lost (when the caller's `await` restores the synchronization context). Here's a very simplified example (in the real code, authentication happens in an action 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("<name>"); var roles = new string[] { }; Thread.CurrentPrincipal = new GenericPrincipal(identity, roles); currentHttpContext.User = Thread.CurrentPrincipal; } } ``` How do you set `Thread.CurrentPrincipal` in an async function such that the caller's `await` doesn't discard that mutation when restoring the synchronization context?