授权处理器无法获取Claims:context.User.Identity.Name始终为Null
解决授权处理器中context.User.Identity.Name为空的问题
问题核心:使用PasswordSignInAsync登录时,ASP.NET Core Identity默认仅生成包含基础身份信息的Cookie,不会自动加载你通过userManager.AddClaimsAsync存入数据库的自定义Claims,导致授权处理器中无法获取到对应值。
下面提供两种可行的解决方法:
方法一:自定义登录逻辑,手动加载Claims
修改登录接口代码,跳过默认的PasswordSignInAsync,手动验证密码并加载用户Claims后完成登录:
[HttpPost("/login")] public async Task<IActionResult> Login(string login, string password) { var user = await mediator.Send(new GetUserByLoginQuery(login)); if (user is null) return Unauthorized("wrong login"); // 手动验证密码有效性 bool isPasswordValid = await userManager.CheckPasswordAsync(user, password); if (!isPasswordValid) { return Unauthorized("wrong password"); } // 从数据库加载用户所有Claims var userClaims = await userManager.GetClaimsAsync(user); // 创建包含Claims的身份标识 var claimsIdentity = new ClaimsIdentity(userClaims, CookieAuthenticationDefaults.AuthenticationScheme); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); // 生成包含完整Claims的登录Cookie await signInManager.SignInAsync(claimsPrincipal, isPersistent: false); return Ok(); }
方法二:配置自定义Claims工厂,自动加载用户Claims
通过自定义UserClaimsPrincipalFactory,让Identity在登录时自动从数据库加载用户Claims,无需修改登录逻辑:
- 创建自定义Claims工厂类:
public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<User> { private readonly UserManager<User> _userManager; public CustomUserClaimsPrincipalFactory(UserManager<User> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor) { _userManager = userManager; } protected override async Task<ClaimsIdentity> GenerateClaimsAsync(User user) { // 先获取基础身份Claims var identity = await base.GenerateClaimsAsync(user); // 添加数据库中存储的用户自定义Claims var userClaims = await _userManager.GetClaimsAsync(user); identity.AddClaims(userClaims); return identity; } }
- 在Program.cs中注册该工厂:
builder.Services.AddScoped<IUserClaimsPrincipalFactory<User>, CustomUserClaimsPrincipalFactory>();
完成以上配置后,使用原有的PasswordSignInAsync登录时,系统会自动将用户的所有Claims加载到身份票据中,授权处理器里就能正常获取context.User.Identity.Name的值了。
额外检查项:
- 确保授权处理器已正确注册到DI容器:
builder.Services.AddScoped<IAuthorizationHandler, RequestLoginIsUserLoginHandler>();
- 确保授权策略配置正确:
builder.Services.AddAuthorization(options => { options.AddPolicy("YourPolicyName", policy => policy.Requirements.Add(new AccessRequirement())); });
内容的提问来源于stack exchange,提问作者Daniil Kozenko
相关产品推荐
相关产品推荐

