.NET 6 Identity Core中CheckPasswordAsync校验密码始终返回false
.NET 6 Identity Core 移动端API密码校验始终返回false排查方案
问题背景
- 运行环境:.NET 6、Identity Core,以邮箱作为用户名,基于MVC架构开发
- 账号创建逻辑如下,创建完成的账号可在Web端正常登录:
var user = new DBModels.ApplicationUser { UserName = "Valid Email", Email = "Valid Email", Approved = true, LockoutEnabled = false, PhoneNumber = "(123) 456-7890", FirstName = "John", LastName = "Doe", EmailConfirmed = true, CreationDate = DateTime.Now, RenewalDate = DateTime.Now.AddYears(50), ScreenName = "John.Doe", State = "AK", Avatar = "/assets/user.png" }; var userResult = _userManager.CreateAsync(user, "Password123!").Result; var roleResult = _userManager.AddToRoleAsync(user, "Default").Result;
问题现象
为配套移动端开发的API登录逻辑如下,调用FindByEmailAsync可正确查询到目标用户,但传入正确密码调用CheckPasswordAsync时始终返回false:
public async Task<IActionResult> Login(string email, string password) { try { var curUser = await UserManager.FindByEmailAsync(email); if (curUser != null) { var verifyPassword = await UserManager.CheckPasswordAsync(curUser, password); if (verifyPassword) .....
排查方向与解决方案
按出现概率从高到低排查:
- 两端Identity密码哈希配置不一致
这是该问题最高发诱因。如果Web端和API端是独立的服务/独立注册Identity服务,两边的密码校验规则、哈希兼容模式配置不一致,会直接导致同一份密码哈希在一端校验通过、另一端校验失败。
核对两端Program.cs/Startup.cs中Identity的配置,确保密码相关规则、哈希兼容模式完全一致:
重点检查是否有一端单独配置了builder.Services.AddIdentityCore<ApplicationUser>(options => { // 以下配置两端必须完全匹配 options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireUppercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequiredLength = 6; }) .AddEntityFrameworkStores<你的数据库上下文类型>();PasswordHasherCompatibilityMode为不同版本(V2/V3),版本不匹配会直接导致哈希校验失败。 - 入参传递过程中密码被篡改
在API方法内打日志打印接收到的password明文,确认移动端提交请求时没有对密码做URL编码、特殊字符(比如示例密码末尾的!)没有被转义截断、大小写没有被自动转换,保证传入校验方法的密码和Web端登录时输入的完全一致。 - 用户核心字段被异常篡改
检查查询到的curUser实体,确认PasswordHash、SecurityStamp字段值和数据库中存储的值完全一致,没有被全局查询过滤器、EF Core拦截器、AutoMapper映射逻辑意外修改或置空。 - 服务注册异常
检查API项目的服务注册逻辑,确认没有重复注册Identity服务、没有替换默认的IPasswordHasher实现,保证UserManager实例使用的密码哈希提供器和Web端完全一致。
内容的提问来源于stack exchange,提问作者BTI-Doug
相关产品推荐
相关产品推荐

