ASP.NET 身份使用ConfigureAwait(false),为什么安全?

ASP.NET Identity uses ConfigureAwait(false), why is it safe?

阅读 ASP.NET Identity 的来源,我注意到一些让我困惑的事情。有几次,我发现他们使用 ConfigureAwait(false) :

/// <summary>
/// Create a ClaimsIdentity from a user
/// </summary>
/// <param name="manager"></param>
/// <param name="user"></param>
/// <param name="authenticationType"></param>
/// <returns></returns>
public virtual async Task<ClaimsIdentity> CreateAsync(
          UserManager<TUser, TKey> manager, TUser user, string authenticationType)
{
    if (manager == null) {
        throw new ArgumentNullException("manager");
    }
    if (user == null) {
        throw new ArgumentNullException("user");
    }
    var id = new ClaimsIdentity(authenticationType, UserNameClaimType, RoleClaimType);
    id.AddClaim(new Claim(UserIdClaimType, ConvertIdToString(user.Id), ClaimValueTypes.String));
    id.AddClaim(new Claim(UserNameClaimType, user.UserName, ClaimValueTypes.String));
    id.AddClaim(new Claim(IdentityProviderClaimType, DefaultIdentityProviderClaimValue, ClaimValueTypes.String));
    if (manager.SupportsUserSecurityStamp) {
        id.AddClaim(new Claim(SecurityStampClaimType, await manager.GetSecurityStampAsync(user.Id).ConfigureAwait(false)));
    }
    if (manager.SupportsUserRole) {
        var roles = await manager.GetRolesAsync(user.Id).ConfigureAwait(false);
        foreach (var roleName in roles) {
            id.AddClaim(new Claim(RoleClaimType, roleName, ClaimValueTypes.String));
        }
    }
    if (manager.SupportsUserClaim) {
        id.AddClaims(await manager.GetClaimsAsync(user.Id).ConfigureAwait(false));
    }
    return id;
}

我理解需要使用它,但我想知道为什么在使用其中一种 ASP.NET 身份方法后依赖请求上下文对我们来说是安全的 - 我假设它是应该的为了安全起见,因为我还没有遇到微软的任何相反指导方针。

我们真的能保证我们会回到正确的环境吗?如果是怎么可能?

I'm wondering why it is safe for us to rely on the request context after using one of the ASP.NET Identity Methods

因为只有他们在 CreateAsync 中使用的内部任务才会忽略上下文。由您的方法创建的 Task(也可能是异步的并调用 CreateAsync)仍将捕获 ASP.NET SynchronizationContext,这将确保您将立即返回正确的请求上下文。

一般来说,这就是异步方法的工作原理。如果任何内部任务使用 ConfigureAwait(false) 忽略上下文,这并不意味着整个调用堆栈现在将脱离上下文,它只是 异步方法 的实现丢弃上下文。