asp.net core系列 48 Identity 身份模型自定义
一.概述
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 表
字段名称 |
字段类型 |
描述 |
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();
});
}
参考文献
自定义Identity
asp.net core系列 48 Identity 身份模型自定义的更多相关文章
- asp.net core系列 46 Identity介绍
一. Identity 介绍 ASP.NET Core Identity是一个会员系统,可为ASP.NET Core应用程序添加登录功能.可以使用SQL Server数据库配置身份以存储用户名,密码和 ...
- ASP.NET Core系列:JWT身份认证
1. JWT概述 JSON Web Token(JWT)是目前流行的跨域身份验证解决方案. JWT的官网地址:https://jwt.io JWT的实现方式是将用户信息存储在客户端,服务端不进行保存. ...
- asp.net core系列 49 Identity 授权(上)
一.概述 授权是指用户能够访问资源的权限,如页面数据的查看.编辑.新增.删除.导出.下载等权限.ASP.NET Core 授权提供了多种且灵活的方式,包括:Razor pages授权约定.简单授权.R ...
- 坎坷路:ASP.NET Core 1.0 Identity 身份验证(中集)
上一篇:<坎坷路:ASP.NET 5 Identity 身份验证(上集)> ASP.NET Core 1.0 什么鬼?它是 ASP.NET vNext,也是 ASP.NET 5,以后也可能 ...
- asp.net core系列 52 Identity 其它关注点
一.登录分析 在使用identity身份验证登录时,在login中调用的方法是: var result = await _signInManager.PasswordSignInAsync(Input ...
- asp.net core系列 47 Identity 自定义用户数据
一.概述 接着上篇的WebAppIdentityDemo项目,将自定义用户数据添加到Identity DB,自定义扩展的用户数据类应继承IdentityUser类, 文件名为Areas / Ident ...
- asp.net core系列 45 Web应用 模型绑定和验证
一. 模型绑定 ASP.NET Core MVC 中的模型绑定,是将 HTTP 请求中的数据映射到action方法参数. 这些参数可能是简单类型的参数,如字符串.整数或浮点数,也可能是复杂类型的参数. ...
- asp.net core系列 51 Identity 授权(下)
1.6 基于资源的授权 前面二篇中,熟悉了五种授权方式(对于上篇讲的策略授权,还有IAuthorizationPolicyProvider的自定义授权策略提供程序没有讲,后面再补充).本篇讲的授权方式 ...
- asp.net core系列 50 Identity 授权(中)
1.5 基于策略的授权 在上篇中,已经讲到了授权访问(authorization)的四种方式.其中Razor Pages授权约定和简单授权二种方式更像是身份认证(authentication) ,因为 ...
随机推荐
- Beta项目总结
Beta冲刺成员名单和工作量比例 姓名 学号 负责内容 工作量比例 张梨贤 170327109 负责企业人员的委托/收回授权.第三方机构的委托授权管理.分级统计展示.分级列表展示 26% 黄腾飞 17 ...
- 解决vue在ios或android中用webview打开H5链接时#号后面的参数被忽略问题angular同样适用
在ios或android如果直接用webview在打开H5链接例如: 打开:http://localhost:8080/#/answer?id=1509335039582001 会变成 http:// ...
- CSS学习笔记3:选择器及优先级
CSS选择器的类型: 标签选择器 类选择器 ID选择器 全局选择器 群组选择器 后代选择器 1.标签选择器: 以HTML的标签作为选择器,凡是选择了一个标签,那么所有这个标签的内容都是用了 ...
- esayui扩展验证方法
下面是关于平时中积累的esayui扩展验证方法仅作记录: /**************************************************************** ...
- 树莓派+花生棒+leanote搭建自己的笔记服务器
背景 对于一个程序猿来说.女朋友可以(暂时)没有,但是不能没有一个很好的记笔记的应用.因为记笔记可以帮助自己积累学习提升自己.每一次回头看自己记得笔记,你都会有新的理解. 也许有人会说,用有道云啊,有 ...
- redis两种持久化方法对比分析
1.前言 最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据.由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能, ...
- linux中~/cut/argus/
1.Linux shell 截取字符变量的前8位 实现方法有如下几种: expr substr "$a" 1 8 echo $a|awk '{print substr(,1,8)} ...
- Linux kernel的中断子系统之(九):tasklet
返回目录:<ARM-Linux中断系统>. 总结: 二介绍了tasklet存在的意义. 三介绍了通过tasklet_struct来抽想一个tasklet,每个CPU维护一个tasklet链 ...
- difference between collection and association mapping in mybatis 3
Mybatis处理“一对多”的关系时,需要用到associasion元素.处理”多对一“用collection元素来实现(这两个元素在之前mapper文件中提到过). 本例子中,假设一名User可以有 ...
- LeetCode Javascript实现 344. Reverse String 292. Nim Game 371. Sum of Two Integers
344. Reverse String /** * @param {string} s * @return {string} */ var reverseString = function(s) { ...