Security, Thread.CurrentPrincipal, and ConfigureAwait(false)

async-await, claims-based-identity, current-principal, executioncontext, synchronizationcontext

Solution

From my tests, it appears that `Thread.CurrentPrincipal` will flow correctly, even if you use `ConfigureAwait(false)`. The following WebAPI code sets the principal and then blocks on an `async` call, forcing another thread to resume the `async` method. That other thread does inherit the correct principal.

private async Task<string> Async()
{
    await Task.Delay(1000).ConfigureAwait(false);
    return "Thread " + Thread.CurrentThread.ManagedThreadId + ": " + Thread.CurrentPrincipal.Identity.Name + "\n";
}

public string Get(int id)
{
    var user = new ClaimsPrincipal(new ClaimsIdentity(
        new[]
        {
            new Claim(ClaimTypes.Name, "Bob"),
        }
    ));
    HttpContext.Current.User = user;
    Thread.CurrentPrincipal = user;

    var ret = "Thread " + Thread.CurrentThread.ManagedThreadId + ": " + Thread.CurrentPrincipal.Identity.Name + "\n";

    ret += Async().Result;

    return ret;
}

When I run this code on a new instance of IISExpress, I get:

"Thread 7: Bob\nThread 6: Bob\n"

However, I should point out that using `ConfigureAwait(false)` to avoid deadlock is not recommended. This is especially true on ASP.NET. If at all possible, use `ConfigureAwait(false)` and also use `async` all the way. Note that WebAPI is a fully-`async` stack and you should be able to do this.

Problem

Would using Thread.CurrentPrincipal's claims in a referenced library that uses ConfigureAwait(false) pose any problems or will the flowing of ExecutionContext's logical call context take care of me there? (my reading and testing so far indicates that it will). Example WebAPI Controller Action: ``` [CustomAuthorizeThatSetsCurrentUsersClaimsToThreadCurrentContextAndHttpContextCurrentUser] public async Task<Order> Get(int orderId) { return await _orderBusinessLogicLibrary.LoadAsync(orderId); // defaults to .ConfigureAwait(true) } ``` Example load functions from external, referenced library: ``` [ClaimsPrincipalPermission( SecurityAction.Demand, Operation="Read", Resource="Orders")] [ClaimsPrincipalPermission( SecurityAction.Demand, Operation="Read", Resource="OrderItems")] public async Task<Order> Load(int orderId) { var order = await _repository.LoadOrderAsync(orderId).ConfigureAwait(false); // here's the key line.. assuming this lower-level function is also imposing // security constraints in the same way this method does, would // Thread.CurrentPrincipal still be correct inside the function below? order.Items = await _repository.LoadOrderItemsAsync(orderId).ConfigureAwait(false); return order; } ``` Also, the answer can't be "well don't use ConfigureAwait(false) then!". That can cause other problems such as deadlock (Don't Block on Async Code).

Original source