阅读 ASP.NET 身份的来源时,我注意到一些让我感到困惑的事情。有几次,我发现他们使用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 身份方法之一后依赖请求上下文是安全的 - 我假设它应该是安全的,因为我没有遇到任何相反的准则Microsoft。
我们真的能保证我们会回到正确的环境中吗?如果是这样,怎么可能?
我想知道为什么我们依赖请求上下文是安全的 使用 ASP.NET 标识方法之一后
因为只有他们在内部使用的内部任务CreateAsync
才会忽略上下文。您的方法创建的Task
(也可能是异步的,并且调用CreateAsync
)仍将捕获 ASP.NET 同步上下文,这将确保您将立即返回到正确的请求上下文中。
一般来说,这就是异步方法的工作方式。如果任何内部任务使用 ConfigureAwait(false)
忽略上下文,这并不意味着整个调用堆栈现在将脱离上下文,只是该异步方法的实现丢弃了上下文。