(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化
一、前言
IdentityServer配合EFCore持久化,框架已经为我们准备了两个上下文:
ConfigurationDbContext:配置数据(资源、客户端、身份等)PersistedGrantDbContext:操作数据(授权码、访问令牌、刷新令牌等)
用户持久化可以自定义一套逻辑,But,我们直接用微软的Identity,再新建一个用户上下文:
ApplicationDbContext:用户数据(用户、角色等)
二、持久化
1、新建认证服务
新建一个MVC工程,目录结构跟上篇内存化大致一样,IdentityServer4.Persistence安装所需包:
IdentityServer4IdentityServer4.EntityFrameworkMicrosoft.EntityFrameworkCore.ToolsNpgsql.EntityFrameworkCore.PostgreSQL(PostgreSQL)IdentityServer4.AspNetIdentity(IdentityServer4支持微软Indentity)Microsoft.AspNetCore.Identity.EntityFrameworkCore(Identity支持EF)

2、新建用户上下文
//IdentityUser实际肯定是需要拓展的,还有一些自定义等功能,Demo这儿就不费劲了,随后要挪到正式的环境,用到再细说
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
3、Startup.cs 配置持久化
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
//读取数据库连接
var connectionString = Configuration.GetSection("DB").Value;
if (connectionString == "")
{
throw new Exception("数据库配置异常");
}
/**********************************IdentityServer4持久化配置**********************************/
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
//添加用户数据上下文 ApplicationDbContext
services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(connectionString));
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
//添加配置数据上下文 ConfigurationDbContext、操作数据上下文 PersistedGrantDbContext、用户持久化
var builder = services.AddIdentityServer()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
{
builder.UseNpgsql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
};
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
{
builder.UseNpgsql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
};
//token配置
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
})
.AddAspNetIdentity<IdentityUser>()
.AddDeveloperSigningCredential();
}
4、迁移到数据库
程序包管理器控制台,依次输入一下命令回车:
add-migration InitialPersisted -c PersistedGrantDbContext -o Migrations/Persistedupdate-database -Context PersistedGrantDbContextadd-migration InitialConfiguration -c ConfigurationDbContext -o Migrations/Configurationupdate-database -Context ConfigurationDbContextadd-migration InitialApplication -c ApplicationDbContext -o Migrations/Applicationupdate-database -Context ApplicationDbContext
数据库表、ER关系图

5、初始化种子数据
新建SeedData.cs,初始化种子数据,使用之前在InMemoryConfig.cs配置好的内存数据
public class SeedData
{
public static void InitData(IApplicationBuilder serviceProvider)
{
using (var scope = serviceProvider.ApplicationServices.CreateScope())
{
//初始化种子数据:配置、资源、客户端等
scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
{
var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
context.Database.Migrate();
InitSeedData(context);
}
//初始化种子数据:用户
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
context.Database.Migrate();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
foreach (var user in InMemoryConfig.GetTestUser())
{
var find = userManager.FindByNameAsync(user.Username).Result;
if (find == null)
{
IdentityUser u = new IdentityUser() { UserName = user.Username };
//密码格式严格(至少一个非字母字符、至少一位0-9数字)
var ret = userManager.CreateAsync(u, "WinterSir123!").Result;
if (ret.Succeeded)
{
userManager.AddClaimsAsync(u, user.Claims);
}
}
}
}
}
}
private static void InitSeedData(ConfigurationDbContext context)
{
if (!context.Clients.Any())
{
foreach (var client in InMemoryConfig.GetClients())
{
context.Clients.Add(client.ToEntity());
}
context.SaveChanges();
}
if (!context.IdentityResources.Any())
{
foreach (var resource in InMemoryConfig.IdentityResources)
{
context.IdentityResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
if (!context.ApiResources.Any())
{
foreach (var resource in InMemoryConfig.GetApiResources())
{
context.ApiResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
if (!context.ApiScopes.Any())
{
foreach (var resource in InMemoryConfig.GetApiScopes())
{
context.ApiScopes.Add(resource.ToEntity());
}
context.SaveChanges();
}
}
}
调用代码放这里,认证服务启动时初始化,之前内存模式配置持久化到数据库


6、修改登录、注销代码**

其实我也没弄白为啥要改登录那块,一般情况都是用框架原生提供的方法才对,百度谷歌不得其解,大佬可以指点一下


三、效果图
**可以看到我们必须要用新密码WinterSir123!才能登录,匹配是已经持久化数据库的信息

四、前任栽树,后人乘凉
https://zhuanlan.zhihu.com/p/352497277
五、代码已上传
https://github.com/WinterSir/IdentityServer4.GrantTypesDemo
(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化的更多相关文章
- (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建
首先,你需要先装一个Nodejs,这是基础哦.如果没有这方面知识的小伙伴可以在园子里搜索cnpm yarn等关键字,内容繁多,此不赘述,参考链接 一. 简介 1. Ant Design Pro v5 ...
- (十)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(二)授权模式
一.前言 先交代一下整个Demo项目结构: 一个认证服务(端口5000)IdentityServer4.Authentication 五个授权模式(两个控制台程序,三个MVC项目端口5001)文件夹G ...
- (三)React Ant Design Pro + .Net5 WebApi:后端环境搭建
一. 简介 1. 平常用的core webapi 3.1,恰逢.Net5.0正式版发布了,直接开整. 2. 先学习IdentityServer4 .Autofac.EF Core,集成到后台框架里. ...
- (六)React Ant Design Pro + .Net5 WebApi:后端环境搭建-EF Core
一. 简介 EFCore 是轻量化.可扩展.开源和跨平台版的常用数据访问技术,走你(官方文档) 二. 使用 1.安装数据库驱动包.PMC 工具包 不同的数据库有不同的包,参考,我用 PostgreSQ ...
- (五)React Ant Design Pro + .Net5 WebApi:后端环境搭建-Autofac注入+ 泛型仓储
一. 简介 Autofac与.Net Core自带DI的区别,大佬级的文章数不胜数.我只是根据实际应用简单介绍(非常简单的那种) 1.批量注入,自带DI需要自己写循环反射注入,Autofac现成方法, ...
- (七)React Ant Design Pro + .Net5 WebApi:后端环境搭建-日志、异常处理
一.日志 日志具有帮助开发者快速的定位问题,记录各种信息,配合其他分析框架使用等等功能,收集日志的各类框架如:Log4net.NLog.Exceptionless.Serilog等等,百度或园子里介绍 ...
- (八)React Ant Design Pro + .Net5 WebApi:后端环境搭建-Aop
一.Aop Aop 面向切面编程(Aspect Oriented Program),在项目中,很多地方都会用到Aop的概念,比如:过滤器(Filter),中间件(Middleware) 通常用来处理数 ...
- (九)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4-简单配置
一.简介 IdentityServer4 是用于 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 框架,通过中间件的方式集成.JWT(json web token) ...
- (一)React Ant Design Pro + .Net5 WebApi:先搞定服务器,顺手装个Nginx
腾讯云搞定服务器,具体过程就不赘述了,文档都有,咨询客服或者自行百度,体验一下过程. 一. 服务器 1. 云服务器 cvm 1核2G centos8.0 2. 域名注册 www.homejok.com ...
随机推荐
- python2,3的区别
python2和python3的区别: 1. python 2x:源代码不规范,源码重复多 python 3x:源码 清晰,简单,优美 2.python 2x:默认编码是ASCII码 编码更改: ...
- Pulsar 也会重复消费?
背景 许久没有分享 Java 相关的问题排查了,最近帮同事一起排查了一个问题: 在使用 Pulsar 消费时,发生了同一条消息反复消费的情况. 排查 当他告诉我这个现象的时候我就持怀疑态度,根据之前使 ...
- 一种优雅的Golang的库插件注册加载机制
一种优雅的Golang的库插件注册加载机制 你好,我是轩脉刃. 最近看到一个内部项目的插件加载机制,非常赞.当然这里说的插件并不是指的golang原生的可以在buildmode中加载指定so文件的那种 ...
- Markdown初识及基本使用
Markdown初识及基本使用 由Typora编写. 一.初识Markdown 允许人们使用易读易写的纯文本格式编写文档. 是一种轻量级标记语言 编写的文档可以导出 HTML .Word.图像.P ...
- 半吊子菜鸟学Web开发3 --Html css学习1
1创建一个html文件,用vscode打开 首先输入一个! 然后就可以开始编辑html文件了 2 整体结构 <!DOCTYPE HTML><html> <head& ...
- JavaScript的访问器
一.访问器属性: 1.Configurable:表示能否通过delete删除属性,从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性.对于直接在对象上定义的属性,这个特性的默认值为tr ...
- 事务的 ACID 是指什么?
原子性(Atomic):事务中各项操作,要么全做要么全不做,任何一项操作 的失败都会导致整个事务的失败: 一致性(Consistent):事务结束后系统状态是一致的: 隔离性(Isolated):并发 ...
- Mac SVN Cornerstone 安装使用详解
Cornerstone 是收费软键,这里提供一个破解版 ,安装后需要输入安装密码:www.ifunmac.com 链接:https://pan.baidu.com/s/1LqY2s8vEJAQ9JJh ...
- kafka producer 源码总结
kafka producer可以总体上分为两个部分: producer调用send方法,将消息存放到内存中 sender线程轮询的从内存中将消息通过NIO发送到网络中 1 调用send方法 其实在调用 ...
- 客户端注册 Watcher 实现?
1.调用 getData()/getChildren()/exist()三个 API,传入 Watcher 对象 2.标记请求 request,封装 Watcher 到 WatchRegistrati ...