You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EF Core InMemory数据库提供程序时出现登录失败的原因

问题场景

自定义AuthUser身份用户类,在EF Core搭配SQL数据库运行时功能完全正常,切换为EF Core InMemory内存数据库提供程序后出现两个异常:

  • 调用UserManager<AuthUser>.FindByNameAsync()方法无法查询到已存在的用户,只能改用UserManager<AuthUser>.Users.FirstOrDefault(u => u.Email == "")的方式查询
  • 即便通过上述方式查询到目标用户,调用SignInManager.PasswordSignInAsync()方法执行登录时,即使输入密码正确也会返回登录失败

排查过程中发现读取AuthUser实体时,NormalizedUserName和NormalizedEmail字段没有按预期转为大写格式,判断是该问题导致异常。先后尝试以下修复方案均未生效:

  • 重写实体的规范化属性,代码如下:
public override string NormalizedUserName { get => base.UserName.ToUpper(); set => base.NormalizedUserName = value; }
  • 创建用户时显式设置这两个规范化字段的值
  • 数据写入后手动更新这两个字段的值
    所有修改在每次通过UserManager读取用户时都会被还原,无法持久化。

关联代码

AuthUser 实体定义

public class AuthUser : Microsoft.AspNetCore.Identity.IdentityUser<string>
{
    public DateTime? LastLogin { get; set; }
    public string? PasswordResetKey { get; set; }
}

实体Fluent API配置

builder
    .ToTable("AspNetUsers");
builder
    .HasKey((e) => e.Id);
builder
    .Property((e) => e.Id)
    .ValueGeneratedOnAdd();
问题原因

SQL Server默认使用不区分大小写的排序规则,哪怕NormalizedUserName、NormalizedEmail字段没有正确存为大写格式,查询时的字符串匹配也能命中,所以不会暴露问题;但InMemory数据库的字符串比较是严格大小写敏感的,Identity内置的用户查询、密码校验前的用户匹配逻辑,都是基于大写规范化后的这两个字段做精确匹配,一旦字段值大小写不符合预期就会匹配失败。

之前尝试的修复方案不生效的核心原因:

  1. 重写属性的写法干扰了EF Core的属性存取逻辑,EF Core读取实体时会直接给属性的支撑字段赋值,不会触发自定义的get/set逻辑,无法自动转换大小写
  2. 直接操作DbContext插入/修改用户数据,绕过了UserManager的内置处理流程,UserManager在跟踪实体时会自动调用内置的规范化器重新处理这两个字段,覆盖手动修改的值
修复方案
  1. 删掉重写的NormalizedUserName属性代码,不要通过实体重写的方式实现规范化逻辑,避免干扰EF Core的正常属性存取
  2. 所有用户创建、更新操作统一通过UserManager的CreateAsync、UpdateAsync方法执行,这些方法内部会自动调用ILookupNormalizer把NormalizedUserName、NormalizedEmail转为大写,同时自动完成密码哈希、安全标记更新等必要逻辑,不要直接操作DbContext增改用户数据
  3. 检查服务配置代码,确保调用了AddIdentity/AddDefaultIdentity/AddIdentityCore方法注册Identity服务,这些方法默认会注册实现大写转换逻辑的ILookupNormalizer,如果之前手动替换过该服务实现,要确保规范化逻辑正确。

内容的提问来源于stack exchange,提问作者Bassie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:36:24