一. 概述
ASP.NET Core Identity 提供了一个框架, 用于管理和存储在 ASP.NET Core 应用中的用户帐户. Identity 添加到项目时单个用户帐户选择作为身份验证机制. 默认情况下, Identity 可以使用的 Entity Framework (EF) Core 数据模型. 本文介绍如何自定义的身份标识模型.
1.1 下面是已经存在的身份模型, 由以下实体类型组成:
实体类型 | 说明 | 关系 |
Users | 登录用户 | |
Roles | 角色 |
|
UserClaims | 用户拥有的权限 | 每个 Users 有多个 UserClaims |
UserTokens | 用户的身份验证令牌 | 每个 Users 有多个 UserTokens |
UserLogins | 将用户与登录相关联。 | 每个 Users 有多个 UserLogins |
RoleClaims | 角色拥有的权限 | 每个 Roles 有多个 RoleClaims |
UserRoles | 用户和角色关联 | 每个 Users 有多个 Roles |
1.2 默认模型的配置
Identity 定义了许多从 DbContext 继承以配置和使用模型的上下文类, 此配置是使用上下文类的 OnModelCreating 方法中的 EF Core Code First Fluent API 完成的. 默认模型结构可以查看 Migration 文件以及查看模型关系 ModelSnapshot 文件, 但要修改模型不在这里更改. 下面是 AspNetUsers 模型代码:
下面是默认模型生成的数据表以及关系:
二. 模型自定义
在 EF 上下文中当重写 OnModelCreating 方法时, base.OnModelCreating 方法首先调用; 接下来重写的会覆盖默认模型配置.
- public class ApplicationDbContext : IdentityDbContext<webAppIdentityDemoUser>
- {
- public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
- : base(options)
- {
- }
- protected override void OnModelCreating(ModelBuilder builder)
- {
- base.OnModelCreating(builder);
- // Customize the ASP.NET Core Identity model and override the defaults if needed.
- // For example, you can rename the ASP.NET Core Identity table names and more.
- // Add your customizations after calling base.OnModelCreating(builder);
- }
- }
2.1 自定义用户数据
在上篇有讲过自定义用户数据, 这里在总结下. 自定义用户数据支持通过继承 IdentityUser 类. 自定义类命名约定 {Application}User.
// 定义 {Application}User 扩展类, 实现用户模型 public class WebAppIdentityDemoUser : IdentityUser // 使用 {Application}User 作为上下文的泛型参数的类型: public class ApplicationDbContext : IdentityDbContext<WebAppIdentityDemoUser> // 更新 Startup.ConfigureServices 以使用新 {Application}User 类, 最后生成迁移, 同步数据库. services.AddDefaultIdentity<WebAppIdentityDemoUser>() .AddDefaultUI() .AddEntityFrameworkStores<ApplicationDbContext>();
2.2 更改主键类型
在创建数据库之后更改 PK 列的数据类型在许多数据库系统上都存在问题. 更改 PK 通常涉及删除和重新创建表. 因此, 在创建数据库时, 应在初始迁移中指定 PK 类型. 下面是更改主键类型步骤:
(1) 删除数据库, 命令如下:
Drop-Database
(2) 移除之前生成的迁移, 命令如下:
Remove-Migration
(3) 修改 user,role 表主键类型, 以及相关代码改动
// 用户表设置主键为 Int public class WebAppIdentityDemoUser : IdentityUser<int> { /// <summary> /// Full name /// </summary> [PersonalData] public string Name { get; set; } /// <summary> /// Birth Date /// </summary> [PersonalData] public DateTime DOB { get; set; } } // 角色表设置主键为 Int public class WebAppIdentityDemoRole : IdentityRole<int> { }
(4) 修改上下文
public class ApplicationDbContext : IdentityDbContext<WebAppIdentityDemoUser, WebAppIdentityDemoRole,int>
(5) 修改服务注册
services.AddIdentity<WebAppIdentityDemoUser, WebAppIdentityDemoRole>() // 如果使用 Identity scaffolder 将 Identity 文件添加到项目中, 请删除对该项目的调用 AddDefaultUI //.AddDefaultUI() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders();
(6) 生成迁移代码, 命令如下
Add-Migration IdentitySchema
(7) 同步数据库
Update-Database IdentitySchema
此时表的主键类型已修改完成, 包括关系表的外键类型也同步更新了, 如下图所示:
2.3 添加导航属性
导航属性仅存在于 EF 模型中, 而不存在于数据库中, 如果导航关系没有改变, 模型更改不需要更新数据库. 如果更改关系的模型配置可能比进行其他更改更困难. 必须注意取代现有的关系. 下面示例是不改变模型关系, 只是在 user 模型上添加导航属性以及在上下文中指定关系:
public class WebAppIdentityDemoUser : IdentityUser<int> { /// <summary> /// Full name /// </summary> [PersonalData] public string Name { get; set; } /// <summary> /// Birth Date /// </summary> [PersonalData] public DateTime DOB { get; set; } // 定义导航属性 public virtual ICollection<IdentityUserClaim<int>> Claims { get; set; } } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // Customize the ASP.NET Core Identity model and override the defaults if needed. // For example, you can rename the ASP.NET Core Identity table names and more. // Add your customizations after calling base.OnModelCreating(builder); builder.Entity<WebAppIdentityDemoUser>(b => { // Each User can have many UserClaims b.HasMany(e => e.Claims) .WithOne() .HasForeignKey(uc => uc.UserId) .IsRequired(); }); }
对于所有用户导航属性, 用户和角色导航属性, 添加所有导航属性. 参考官网文档.
2.4 更改表 / 列名称, 字段长度 (上下文中更改)
protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // 更改表名称 builder.Entity<IdentityUser>(b => { b.ToTable("MyUsers"); }); // 更改表字段名称 builder.Entity<IdentityUserClaim<string>>(b => { b.Property(e => e.ClaimType).HasColumnName("CType"); b.Property(e => e.ClaimValue).HasColumnName("CValue"); }); // 更改长度 builder.Entity<IdentityUser>(b => { b.Property(u => u.UserName).HasMaxLength(128); }); }
参考文献
自定义 Identity
来源: https://www.cnblogs.com/MrHSR/p/10593987.html