一.概述

  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) Users 表

字段名称

字段类型

描述

IdGuid主键,默认是Guid
UserNameNvarchar(256)用户名或邮箱
NormalizedUserNameNvarchar(256)规范化用户名,转成了大写
EmailNvarchar(256)邮箱
NormalizedEmailNvarchar(256)规范化邮箱名,转成了大写
EmailConfirmedbit验证邮件确认,默认为false
PasswordHashNvarchar(max)密码哈希
SecurityStampNvarchar(max)安全标记,Guid类型,用户凭据更改时生成随机值,如更改用户名
ConcurrencyStampNvarchar(max)同步标记,Guid类型
PhoneNumberNvarchar(max)电话
PhoneNumberConfirmedbit>电话确认
TwoFactorEnabledbit双因子验证
LockoutEnddatetimeoffset(7)锁定的到期日期,null表示没有锁定
LockoutEnabledbit是否可以被锁定
AccessFailedCountint登陆失败的次数, 确定是否锁定用户

    

  1.2 默认模型的配置

    Identity定义了许多从DbContext继承以配置和使用模型的上下文类,此配置是使用上下文类的OnModelCreating方法中的EF Core Code First Fluent API完成的。默认模型结构可以查看Migration文件以及查看模型关系ModelSnapshot文件,但要修改模型不在这里更改。下面是AspNetUsers模型代码:

asp.net core系列 48 Identity  身份模型自定义-LMLPHP

    下面是默认模型生成的数据表以及关系: 

asp.net core系列 48 Identity  身份模型自定义-LMLPHP

  

二.模型自定义

   在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

    此时表的主键类型已修改完成,包括关系表的外键类型也同步更新了,如下图所示:

asp.net core系列 48 Identity  身份模型自定义-LMLPHP

  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();
});
}

  参考文献

    自定义Identity

04-24 17:13
查看更多