ASP.NET Core Identity提供了一個框架,用於管理和存儲在 ASP.NET Core 應用中的用戶賬戶。 Identity添加到項目時單個用戶賬戶選擇做爲身份驗證機制。 默認狀況下,Identity可使用的 Entity Framework (EF) Core 數據模型。 本文介紹如何自定義的身份標識模型。數據庫
1.1 下面是已經存在的身份模型, 由如下實體類型組成:安全
實體類型框架 |
說明ide |
關係ui |
Users(用戶表) | 登陸用戶 | |
Roles (角色表)spa |
角色3d |
|
UserClaims(用戶聲明表) | 用戶擁有的權限 | 每一個Users 有多個UserClaims |
UserTokens | 用戶的身份驗證令牌 | 每一個Users 有多個UserTokens |
UserLogins | 將用戶與登陸相關聯。 | 每一個Users 有多個UserLogins |
RoleClaims(角色聲明表) | 角色擁有的權限 | 每一個Roles 有多個RoleClaims |
UserRoles | 用戶和角色關聯 | 每一個Users 有多個Roles |
(1) Users 表code
字段名稱orm |
字段類型blog |
描述 |
Id | Guid | 主鍵,默認是Guid |
UserName | Nvarchar(256) | 用戶名或郵箱 |
NormalizedUserName | Nvarchar(256) | 規範化用戶名,轉成了大寫 |
Nvarchar(256) | 郵箱 | |
NormalizedEmail | Nvarchar(256) | 規範化郵箱名,轉成了大寫 |
EmailConfirmed | bit | 驗證郵件確認,默認爲false |
PasswordHash | Nvarchar(max) | 密碼哈希 |
SecurityStamp | Nvarchar(max) | 安全標記,Guid類型,用戶憑據更改時生成隨機值,如更改用戶名 |
ConcurrencyStamp | Nvarchar(max) | 同步標記,Guid類型 |
PhoneNumber | Nvarchar(max) | 電話 |
PhoneNumberConfirmed | bit> | 電話確認 |
TwoFactorEnabled | bit | 雙因子驗證 |
LockoutEnd | datetimeoffset(7) | 鎖定的到期日期,null表示沒有鎖定 |
LockoutEnabled | bit | 是否能夠被鎖定 |
AccessFailedCount | int | 登錄失敗的次數, 肯定是否鎖定用戶 |
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