一、前言

IdentityServer配合EFCore持久化,框架已经为我们准备了两个上下文:

  • ConfigurationDbContext:配置数据(资源、客户端、身份等)
  • PersistedGrantDbContext:操作数据(授权码、访问令牌、刷新令牌等)

用户持久化可以自定义一套逻辑,But,我们直接用微软的Identity,再新建一个用户上下文:

  • ApplicationDbContext:用户数据(用户、角色等)

二、持久化

1、新建认证服务

新建一个MVC工程,目录结构跟上篇内存化大致一样,IdentityServer4.Persistence安装所需包:

  • IdentityServer4
  • IdentityServer4.EntityFramework
  • Microsoft.EntityFrameworkCore.Tools
  • Npgsql.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/Persisted
  • update-database -Context PersistedGrantDbContext
  • add-migration InitialConfiguration -c ConfigurationDbContext -o Migrations/Configuration
  • update-database -Context ConfigurationDbContext
  • add-migration InitialApplication -c ApplicationDbContext -o Migrations/Application
  • update-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(三)持久化的更多相关文章

  1. (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建

    首先,你需要先装一个Nodejs,这是基础哦.如果没有这方面知识的小伙伴可以在园子里搜索cnpm yarn等关键字,内容繁多,此不赘述,参考链接 一. 简介 1. Ant Design Pro v5 ...

  2. (十)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(二)授权模式

    一.前言 先交代一下整个Demo项目结构: 一个认证服务(端口5000)IdentityServer4.Authentication 五个授权模式(两个控制台程序,三个MVC项目端口5001)文件夹G ...

  3. (三)React Ant Design Pro + .Net5 WebApi:后端环境搭建

    一. 简介 1. 平常用的core webapi 3.1,恰逢.Net5.0正式版发布了,直接开整. 2. 先学习IdentityServer4 .Autofac.EF Core,集成到后台框架里. ...

  4. (六)React Ant Design Pro + .Net5 WebApi:后端环境搭建-EF Core

    一. 简介 EFCore 是轻量化.可扩展.开源和跨平台版的常用数据访问技术,走你(官方文档) 二. 使用 1.安装数据库驱动包.PMC 工具包 不同的数据库有不同的包,参考,我用 PostgreSQ ...

  5. (五)React Ant Design Pro + .Net5 WebApi:后端环境搭建-Autofac注入+ 泛型仓储

    一. 简介 Autofac与.Net Core自带DI的区别,大佬级的文章数不胜数.我只是根据实际应用简单介绍(非常简单的那种) 1.批量注入,自带DI需要自己写循环反射注入,Autofac现成方法, ...

  6. (七)React Ant Design Pro + .Net5 WebApi:后端环境搭建-日志、异常处理

    一.日志 日志具有帮助开发者快速的定位问题,记录各种信息,配合其他分析框架使用等等功能,收集日志的各类框架如:Log4net.NLog.Exceptionless.Serilog等等,百度或园子里介绍 ...

  7. (八)React Ant Design Pro + .Net5 WebApi:后端环境搭建-Aop

    一.Aop Aop 面向切面编程(Aspect Oriented Program),在项目中,很多地方都会用到Aop的概念,比如:过滤器(Filter),中间件(Middleware) 通常用来处理数 ...

  8. (九)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4-简单配置

    一.简介 IdentityServer4 是用于 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 框架,通过中间件的方式集成.JWT(json web token) ...

  9. (一)React Ant Design Pro + .Net5 WebApi:先搞定服务器,顺手装个Nginx

    腾讯云搞定服务器,具体过程就不赘述了,文档都有,咨询客服或者自行百度,体验一下过程. 一. 服务器 1. 云服务器 cvm 1核2G centos8.0 2. 域名注册 www.homejok.com ...

随机推荐

  1. Linux-Centos7学习笔记

    镜像下载.域名解析.时间同步请点击阿里云开源镜像站 下载.安装与配置 下载 下载Centos镜像,网站见参考 点击大的版本,例如7,再选择isos进行下载 安装 这里使用的VMware 12 Pro, ...

  2. ZYNQ使用88E1510 PHY芯片的驱动程序

    SDK V2014.4 PHY 88E1510 PL端以太网,自协商 standalone应用程序 PL端设计,略. 根据PL端生成的hdf,新建项目,采用官方lwip echo server例程.发 ...

  3. 远程调用NFS超时,服务卡死

    远程调用NFS超时,服务卡死 如何查看进程中使用了哪些文件句柄?

  4. 『现学现忘』Docker基础 — 31、实现MySQL同步数据

    目录 1.搜索镜像 2.拉取镜像 3.查看镜像 4.启动镜像 5.操作容器 (1)在MySQL中创建数据库 (2)外部连接Dokcer容器中的MySQL服务 (3)查看挂载情况 (4)测试MySQL服 ...

  5. 突发!Gitee 图床,废了!

    大家好,我是鱼皮,这两天又发生了一件挺意外的事情:Gitee 的图床废了! 图床:指储存图片的服务器,便于在网上展示图片 昨天晚上,星球里不止一位小伙伴发帖子表示自己网站.文章中的图片竟然全部变成了 ...

  6. Mybatis入门实例解析

    写在前面:本文全程根据Mybatis官网进行入门讲解.毫无疑问,官方文档是学习这门技术最权威的资料,与此同时我们也知道官方文档对待入门小白基本上不太友好,没有入门demo.开篇就是小白们不懂的内容.有 ...

  7. Prometheus+alertmanager告警配置-2

    prometheus 告警 prometheus 通过alertmanager进行告警 实现监控告警的步骤: 在prometheus中定义告警规则rule_files alertmanager配置告警 ...

  8. 【VNCTF2022】Reverse wp

    babymaze 反编译源码 pyc文件,uncompy6撸不出来,看字节码 import marshal, dis fp = open(r"BabyMaze.pyc", 'rb' ...

  9. Mysql查询优化器之关于子查询的优化

    下面这些sql都含有子查询: mysql> select * from t1 where a in (select a from t2); mysql> select * from (se ...

  10. 请说一说Servlet的生命周期?

    servlet有良好的生存期的定义,包括加载和实例化.初始化.处理请求以及服务结束.这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达. Se ...