如何让Identity Server与用户管理应用共享AspNet Identity用户表?
这个问题我之前帮同事排查过,核心原因是ASP.NET Identity默认会给表名加上AspNet前缀,而你的Identity Server用的是不带前缀的自定义表名,导致EF Core把它们当成了两套完全独立的实体集合,自然会生成新表。下面是具体的解决步骤:
1. 保持两边的用户实体类完全一致
你的用户管理应用中的ApplicationUser类,必须和Identity Server项目中使用的用户实体类完全匹配——包括所有自定义属性、主键类型(默认是string,如果改了要两边统一)。如果两边实体类结构不一样,EF Core会判定为不同的实体,还是会生成新表。
比如如果Identity Server的用户类有NickName属性,你的ApplicationUser也要定义同样的属性:
public class ApplicationUser : IdentityUser { public string NickName { get; set; } // 其他自定义属性和Identity Server那边保持一致 }
2. 在DbContext中显式映射表名
在用户管理应用的ApplicationIdentityDbContext的OnModelCreating方法里,手动覆盖默认的表名映射,指向你Identity Server已经存在的表。注意要先调用base.OnModelCreating(builder),再覆盖配置:
protected override void OnModelCreating(ModelBuilder builder) { // 先让Identity的默认配置生效 base.OnModelCreating(builder); // 映射到你已有的自定义表名 builder.Entity<ApplicationUser>().ToTable("Users"); builder.Entity<IdentityRole>().ToTable("Roles"); builder.Entity<IdentityUserRole<string>>().ToTable("UserRoles"); builder.Entity<IdentityUserClaim<string>>().ToTable("UserClaims"); builder.Entity<IdentityUserLogin<string>>().ToTable("UserLogins"); builder.Entity<IdentityRoleClaim<string>>().ToTable("RoleClaims"); builder.Entity<IdentityUserToken<string>>().ToTable("UserTokens"); }
3. 清理错误迁移并重新生成正确的迁移
之前生成的带AspNet前缀的表是错误的,需要清理后重新生成迁移:
- 先删除用户管理应用中
Migrations文件夹下的所有迁移文件 - 如果已经把错误迁移更新到数据库了,先回滚到初始状态:
Update-Database -Migration 0 - 移除残留的迁移记录:
Remove-Migration - 重新生成针对已有表的迁移(比如添加自定义属性的迁移):
Add-Migration AddCustomUserAttributes - 最后更新数据库,这时候EF Core会修改已有的
Users等表,而不是创建新表:Update-Database
4. 确保Identity配置与Identity Server一致
在用户管理应用的启动配置(Program.cs或Startup.cs)中,要使用正确的连接字符串(和Identity Server用同一个数据库),并配置Identity使用你的ApplicationUser和ApplicationIdentityDbContext:
// 配置DbContext,连接到Identity Server的数据库 builder.Services.AddDbContext<ApplicationIdentityDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("IdentityServerDb"))); // 配置Identity使用自定义实体和DbContext builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = false) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<ApplicationIdentityDbContext>();
做完这些步骤后,用户管理应用的UserManager和RoleManager就会操作你原来的Users、Roles等表,和Identity Server共享同一套用户存储了。
内容的提问来源于stack exchange,提问作者mker

