ASP.NET Core Identity登录跳转改密页时出现空用户ID加载失败问题
核心问题:未正确获取当前登录用户对象
你在Login.cshtml.cs的OnPostAsync方法中直接使用了user.IsChangedPassword,但**user变量并未被正确初始化或获取**。PasswordSignInAsync成功仅代表账号密码验证通过,不会自动填充user对象,此时直接访问user会导致后续跳转ChangePassword页面时无法获取有效用户ID,从而抛出Unable to load user with ID ''错误。
具体修复步骤
1. 完善Login.cshtml.cs中的用户获取逻辑
在result.Succeeded分支内,先通过UserManager根据用户名获取用户对象,再判断IsChangedPassword字段:
var result = await _signInManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe, lockoutOnFailure: false); if (result.Succeeded) { // 关键:先从UserManager获取当前用户对象 var user = await _userManager.FindByNameAsync(Input.UserName); if (user != null && !user.IsChangedPassword) { return RedirectToPage("./Manage/ChangePassword"); } else { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } }
注意:确保Login页面的构造函数已注入
UserManager<MyCustomUser>,否则需要补充注入代码:private readonly SignInManager<MyCustomUser> _signInManager; private readonly ILogger<LoginModel> _logger; private readonly UserManager<MyCustomUser> _userManager; // 添加声明 public LoginModel(SignInManager<MyCustomUser> signInManager, ILogger<LoginModel> logger, UserManager<MyCustomUser> userManager) { _signInManager = signInManager; _logger = logger; _userManager = userManager; // 注入UserManager }
2. 检查Program.cs中的Identity配置完整性
你使用的AddIdentityCore是Identity的轻量核心服务,缺少部分默认认证上下文配置,可能导致登录后HttpContext.User的身份信息不完整。建议替换为AddIdentity(包含完整的认证、授权服务):
// 替换原AddIdentityCore为AddIdentity builder.Services.AddIdentity<MyCustomUser, MyCustomRoles>(options => { // 保留原配置项 options.SignIn.RequireConfirmedAccount = false; options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 6; options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; options.User.RequireUniqueEmail = true; }) .AddDefaultTokenProviders() .AddEntityFrameworkStores<MyDBIdentityContext>();
AddIdentity会自动注册SignInManager、UserManager等服务,无需手动添加.AddSignInManager<SignInManager<MyCustomUser>>()。
3. 验证ChangePassword页面的用户获取逻辑
默认ChangePassword.cshtml.cs中通过UserManager.GetUserAsync(User)获取当前用户,依赖HttpContext.User的身份信息正确。如果上述两步修复后仍有问题,可在ChangePassword页面的OnGetAsync方法中手动验证用户ID:
public async Task<IActionResult> OnGetAsync() { var user = await _userManager.GetUserAsync(User); if (user == null) { return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); } // 其他逻辑... }
确保_userManager.GetUserId(User)能返回有效ID,否则说明登录后的身份Claims缺失,需要检查Identity的Claims配置。
额外注意事项
- 确认数据库中
AspNetUsers表的IsChangedPassword字段已正确映射(自定义MyCustomUser类配置正确,且数据库迁移已执行)。 - 测试时需确保目标用户的
IsChangedPassword字段确实为false,且用户名/密码验证通过。
内容的提问来源于stack exchange,提问作者Aequitas

