IdentityServer4系列 | 支持数据持久化

一、前言

在前面的篇章介绍中,一些基础配置如API资源、客户端资源等数据以及使用过程中发放的令牌等操作数据,我们都是通过将操作数据和配置数据存储在内存中进行实现的,而在实际开发生产中,我们需要考虑如何处理数据持久化呢?

这时「IdentityServer4」具有良好的扩展性,其中一个可扩展点是用于「IdentityServer」所需数据的存储机制,进行持久化操作。

下面将如何配置「IdentityServer」以使用「EntityFramework」(EF)作为此数据的存储机制把这些数据存储到「Sql Server」数据库, 这样更符合我们实际生产环境的需求。

二、初识

在我们的 「IdentityServer4」中官方定义的两个上下文,是有两种类型的数据需要持久化到数据库中:

1、「配置数据」(资源、客户端、身份);//这里是对应配置上下文 ConfigurationDbContext

2、「IdentityServer」在使用时产生的 「操作数据」(令牌,代码和用户的授权信息consents);//这里是对应操作上下文 PersistedGrantDbContext

「这两个上下文以及对应的数据模型,已经被 IdentityServer4 官方给封装好了」, 我们不需要做额外的操作,直接进行迁移即可使用。

2.1 ConfigurationDb

ConfigurationDbContext (IdentityServer configuration data) —— 负责数据库中对客户端、资源和 CORS 设置的配置存储;

如果需要从 EF 支持的数据库加载客户端、标识资源、API 资源或 CORS 数据 (而不是使用内存中配置), 则可以使用配置存储。此支持提供 IClientStoreIResura StoreICorsPolicyService 扩展性点的实现。这些实现使用名为 ConfigurationDbContext「dbcontext」 派生类对数据库中的表进行建模。

2.2 PersistedGrantDb

PersistedGrantDbContext (IdentityServer operational data.) -—— 负责存储同意、授权代码、刷新令牌和引用令牌;

如果需要从 EF 支持的数据库 (而不是默认的内存数据库) 加载授权授予、同意和令牌 (刷新和引用), 则可以使用操作存储。此支持提供了 IPersistedGrantStore 扩展点的实现。实现使用名为 PersistedGrantDbContext「dbcontext」 派生类对数据库中的表进行建模。

三、实践

3.1 新建站点

建立一个MVC的Asp.Net Core项目 ,使用MVC模板

3.2 Nuget包

IdentityServer4.EntityFramework以及EF相关包

1.IdentityServer4
2.IdentityServer4.AspNetIdentity
3.IdentityServer4.EntityFramework

因为本文中使用的是SqlServer数据库,所以需要安装对应的EF程序包对数据库的支持。

Microsoft.EntityFrameworkCore.SqlServer

3.3 数据库上下文

appsettings.json

  "ConnectionStrings": {"DataContext": "data source=.;initial catalog=Yuan.Idp;user id=sa;password=123456;",   }

配置连接数据库

 var connectionString = Configuration.GetConnectionString("DataContext");if (connectionString == ""){throw new Exception("数据库配置异常");}

2.配置数据库服务

在startup.cs中ConfigureServices方法添加如下代码:

        public void ConfigureServices(IServiceCollection services){services.AddControllersWithViews();var connectionString = Configuration.GetConnectionString("DataContext");if (connectionString == ""){throw new Exception("数据库配置异常");}var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;// in DB  configvar builder = services.AddIdentityServer(options =>{options.Events.RaiseErrorEvents = true;options.Events.RaiseInformationEvents = true;options.Events.RaiseFailureEvents = true;options.Events.RaiseSuccessEvents = true;}).AddConfigurationStore(options => //添加配置数据(ConfigurationDbContext上下文用户配置数据){options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));}).AddOperationalStore(options =>   //添加操作数据(PersistedGrantDbContext上下文 临时数据(如授权和刷新令牌)){options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));// 自动清理 token ,可选options.EnableTokenCleanup = true;// 自动清理 token ,可选options.TokenCleanupInterval = 30;}).AddTestUsers(TestUsers.Users);// not recommended for production - you need to store your key material somewhere securebuilder.AddDeveloperSigningCredential();services.ConfigureNonBreakingSameSiteCookies();}

3.4 迁移数据

3.4.1 控制台迁移

方法一:

需要添加EF工具,安装Microsoft.EntityFrameworkCore.Tools, 进行迁移

  1、add-migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/PersistedGrantDb 2、add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/ConfigurationDb 3、update-database -Context PersistedGrantDbContext4、update-database -Context ConfigurationDbContext   

3.4.2 在命令窗口

方法二:

判断是否支持命令行迁移,你可以在项目所在的目录下打开一个命令 Power shell 并运行命令 dotnet ef, 它应该是这样的:

dotnet ef 无法执行,因为找不到指定的命令或文件

从 3.0 起,EF Core 命令列工具 (dotnet ef) 不在 .NET Core SDK 里面,需另装。命令如下:

dotnet tool install --global dotnet-ef

要创建迁移,请在IdentityServer项目目录中打开命令提示符。在命令提示符下运行这两个命令:

1. dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/PersistedGrantDb
2. dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/ConfigurationDb#生成
1. update-database -c PersistedGrantDbContext   
2. update-database -c ConfigurationDbContext  

3.5 显示数据库

(图片来自网络)

3.6 初始化数据库

在之前的篇章中,我们是定义的内存配置数据实现的操作,而在本篇中,我们进行数据持久化操作,可以将之前内存的数据作为种子处理迁移到创建的数据库中进行初始化操作。

参考文章: 用户数据迁移

3.6.1 创建文件

创建SeedData.cs文件,用于初始化基础数据:

    public class SeedData{public static void EnsureSeedData(IServiceProvider serviceProvider){Console.WriteLine("Seeding database...");using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()){scope.ServiceProvider.GetService<PersistedGrantDbContext>().Database.Migrate();var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();context.Database.Migrate();EnsureSeedData(context);}Console.WriteLine("Done seeding database.");Console.WriteLine();}private static void EnsureSeedData(ConfigurationDbContext context){if (!context.Clients.Any()){Console.WriteLine("Clients 正在初始化");foreach (var client in Config.GetClients){context.Clients.Add(client.ToEntity());}context.SaveChanges();}if (!context.IdentityResources.Any()){Console.WriteLine("IdentityResources 正在初始化");foreach (var resource in Config.GetIdentityResources){context.IdentityResources.Add(resource.ToEntity());}context.SaveChanges();}if (!context.ApiResources.Any()){Console.WriteLine("ApiResources 正在初始化");foreach (var resource in Config.GetApiResources){context.ApiResources.Add(resource.ToEntity());}context.SaveChanges();}if (!context.ApiScopes.Any()){Console.WriteLine("ApiScopes 正在初始化");foreach (var resource in Config.GetApiScopes){context.ApiScopes.Add(resource.ToEntity());}context.SaveChanges();}}}

配置内容可以查看之前篇章内容文件Config.cs 或者项目地址.

3.6.2 调用方法

然后我们可以从主入口Main方法调用它:

        public static void Main(string[] args){var seed = args.Contains("/seed");if (seed){args = args.Except(new[] { "/seed" }).ToArray();}var host = CreateHostBuilder(args).Build();if (seed){SeedData.EnsureSeedData(host.Services);}host.Run();}

3.6.3 程序运行

输入 dotnet run /seed

3.6.4 效果

四、问题

4.1 提示找不到上下文

上面我们说到了的两个上下文,如果我们直接通过执行迁移命令是会报错的,比如我们直接迁移 PersistedGrantDbContext 上下文:

因为迁移的目标不匹配,需要更改迁移程序集,如

options.UseSqlServer(connection, b => b.MigrationsAssembly("Ids4.EFCore"))

所以,就需要在项目中配置对应的服务,我们在 startup.cs 启动文件中,配置服务 ConfigureService ,配置 EF 操作数据库.

解决方法 : 可参考上面的实践部分中的「数据库上下文」.

  1. 获取数据库连接字符串

  2. 配置数据库服务

4.2 dotnet ef 无法执行

因为找不到指定的命令或文件

从 3.0 起,EF Core 命令列工具 (dotnet ef) 不在 .NET Core SDK 里面,需另装。命令如下:

dotnet tool install --global dotnet-ef

五、总结

  1. 简单介绍了「IdentityServer4」持久化存储机制相关配置和操作数据,实现了数据迁移,及应用程序的实践。

  2. 本篇未对用户进行持久化操作存储说明,因为「IdentityServer4」本就支持了接入其他认证方式,所以自己根据需要进行合理「扩展」的,比如我们可以使用 「Asp.Net Core 自带的 Identity」 身份认证机制来「实现扩展」,当然,你也可以自己定义相应的操作,在后续篇章中会进行说明介绍。

  3. 如果有不对的或不理解的地方,希望大家可以多多指正,提出问题,一起讨论,不断学习,共同进步。

  4. 项目地址

https://github.com/i3yuan/Yuan.IdentityServer4.Demo/tree/main/DiffAuthMode/EntityFrameworkStorage

六、附加

「EF支持持久化配置和操作数据」

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言修仙受控可看吗,强推三本神奇到爆的小说,c语言修仙,程序员与修真会擦出什么火花...

大家好&#xff0c;我是小龙。今天我给大家推荐三本神奇到爆的小说&#xff0c;c语言修仙&#xff0c;程序员与修真会擦出什么火花!一《c语言修仙》【一十四洲】【简介】: 林浔是一个程序员&#xff0c;通宵编代码后发现自己身体内多了一个程序输入窗口。他尝试编了一个循环程序…

【Vue】Vue与ASP.NET Core WebAPI的集成

SPA单页面应用已经遍地开花&#xff0c;熟知的三大框架&#xff0c;Angular、Vue和React&#xff0c;其中Angular与React均可集成至ASP.NET Core&#xff0c;且提供了相关了中间件。但是Vue没有:“As far as I’m aware, we don’t have plans to introduce Vue-specific featu…

引入Jaeger——封装

随着微服务的普及&#xff0c;微服务间的调用全链路跟踪也火了起来&#xff0c;Jaeger(https://www.jaegertracing.io/)是CNCF孵化的全链路跟踪型项目&#xff0c;在.net core中&#xff0c;提供了一个Jaeger的Nuget(https://github.com/jaegertracing/jaeger-client-csharp)包…

临近年关,发生两起磁盘占满引发的服务下线故障

一口气说两个因为磁盘空间不足引发的应用故障。作为拿起键盘一把梭的Coder&#xff0c; 开发--->部署-->收工--->心旷神怡&#xff0c;滋一口82年的可乐.过了几个月&#xff0c;服务突然下线了&#xff01;CTO又有杀程序员祭天的理由了!事故1&#xff1a;Azure App Se…

c语言幼儿园积木游戏,幼儿园《积木游戏》课件【三篇】

【导语】课件制作本身就是作者综合素养的一种体现&#xff0c;它显现出制作者对教育、教学、教材改革方向的把握&#xff0c;对课堂教学的理解&#xff0c;对现代教育技术的领悟。因此教师在设计课件时一定要吃透教学内容&#xff0c;设计出符合教学的方案用于课件。下面是无忧…

蚂蚁调度AntJob-分布式任务调度系统

分布式任务调度系统&#xff0c;纯NET打造的重量级大数据实时计算平台&#xff0c;万亿级调度经验积累&#xff01;面向中小企业大数据分析场景。开源地址&#xff1a;https://github.com/NewLifeX/AntJob使用教程&#xff1a;https://www.yuque.com/smartstone/blood/antjob体…

c语言怎么让图形界面单独显示,「分享」C语言如何编写图形界面

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼贴吧内经常有人问C语言是不是只能用于字符终端界面开发&#xff0c;不能用于图形界面。大家也都有回答&#xff0c;需要其他的库。MFC&#xff0c;GTK&#xff0c;QT。本人近期刚用GTK库加上纯C写成了第一个LINUX实用程序。现在与大…

如何在 ASP.NET Core 中 自定义中间件

ASP.NET Core 是一个跨平台&#xff0c;开源的&#xff0c;轻量级&#xff0c;高性能 并且高度模块化的web框架&#xff0c;同时扩展性也是非常强&#xff0c;你可以在 request -> response 请求管道中安插各种中间件来根据自己的场景定制化&#xff0c;比如说&#xff1a;监…

ASP.NET Core Authentication and Authorization

最近把一个Asp .net core 2.0的项目迁移到Asp .net core 3.1&#xff0c;项目启动的时候直接报错:InvalidOperationException: Endpoint CoreAuthorization.Controllers.HomeController.Index (CoreAuthorization) contains authorization metadata, but a middleware was not …

android dialog 自定义布局,如何设置AlertDialog的自定义布局?

调用我的对话框:alertDialog showInfoDialog(message "$wrongPasscodeMessage\n$retryMessage")方法如下:fun FragmentActivity.showInfoDialog(message: String?): AlertDialog? {return try {val customLayout layoutInflater.inflate(R.layout.custom_layout…

android 打开谷歌导航,国内开启google位置记录功能/android版google maps 7+上,恢复位置记录功能在国内使用(需root)...

android版google 地图在 7以后的版本上&#xff0c;位置记录功能在国内不能用了&#xff0c;提示本功能不能在中国使用。至少对本人&#xff0c;“位置记录”功能是非常有用的功能&#xff0c;尤其是骑车出行时记录自己的路线。目前还没找到替代产品。之前一段时间内恢复回旧版…

程序员过关斩将--少年派登录安全的奇幻遐想

“据说&#xff0c;这篇也是快餐&#xff0c;完全符合年轻人口味说到登录&#xff0c;无人不知无人不晓。每一个有用户体系的相关系统都会有登录的入口&#xff0c;登录是为了确认操作人的正确性。说到登录安全&#xff0c;其实是一个很伟大的命题&#xff0c;不过常用的手段也…

C# 9 新特性 —— 增强的 foreach

C# 9 新特性 —— 增强的 foreachIntro在 C# 9 中增强了 foreach 的使用&#xff0c;使得一切对象都有 foreach 的可能我们来看一段代码&#xff0c;这里我们试图遍历一个 int 类型的值思考一下&#xff0c;我们可以怎么做使得上面的代码编译通过呢&#xff1f;迭代器模式迭代器…

android系统休眠发广播,Android - BroadcastReceiver

BroadcastReceiverBroadcastReceiver&#xff0c;广播接收者&#xff0c;用来接收系统和应用的广播&#xff0c;并做出相应的处理&#xff0c;如电量过低时提示用户充电等&#xff1b;BroadcastReceiver 是 Android 的四大组件之一&#xff0c;分为 普通广播、有序广播、粘性广…

开源·共享·创新|2020年中国.NET开发者大会圆满收官!

“疫情无限续费”的2020年&#xff0c;对于14亿中国人而言&#xff0c;是必须习惯口罩长在来脸上的一年&#xff1b;是各种线下聚会&#xff0c;被迫数次延期、滞后、云上举办的一年&#xff1b;……而对于潜心修行&#xff0c;静蓄能量的中国.NET开发者而言&#xff0c;2020绝…

android+百度lbs云,百度——LBS.云 v2.0——云存储扩展字段——Android

今天要解决两个问题&#xff1a;1云存储扩展字段2上传的数据是乱码3android版本上传数据到云端使用了一段时间LBS云功能之后&#xff0c;随着对系统的熟悉&#xff0c;默认提供的字段&#xff0c;肯定无法满足需要。比如增加注释&#xff0c;价格&#xff0c;档次等字段的时候。…

年终将至,回顾我们一起走过的 2020

又到了年终末尾匆匆忙忙的 2020 似乎按下了倍速键一晃眼我们就从夏天走到了冬天在这不平凡的一年中我们同途共进也笑着成长让我们跟随着六大年度词条重温这一年我们共同经历的值得骄傲的瞬间吧&#xff01;点击文内高亮部分&#xff0c;阅读文章了解更多人才“倍”出星桥计划出…

灵魂拷问:你和大佬,技术差距有多大?

今天咱们聊点技术以外的内容。前几天&#xff0c;有程序员在某个坛子上发帖吐槽&#xff0c;新来的应届生张嘴就是分布式&#xff0c;一堆框架&#xff0c;可代码根本不会写。马上有人跟贴说自己也遇到过这种情况&#xff0c;说之前自己遇到过一个应届生&#xff0c;开口闭口动…

达梦数据查询编码_查询数据库的编码方式

在Mysql中(1)查看Mysql数据库编码show variables like character_set_database 或者 show create database 数据库名称(2)查看Mysql中某张表的编码show create table 表名show create database 数据库名称、show create table 表名 &#xff0c;还能够显示建库和建表语句。(3)…

玩转git-flow工作流-分支解析

概述搞开发的相信大部分人git天天都在用&#xff0c;那么一般我们在实际工程当中&#xff0c;遵循一个合理、清晰的Git使用流程&#xff0c;是非常重要的。否则&#xff0c;每个人都提交一堆杂乱无章的commit&#xff0c;项目很快就会变得难以协调和维护。那么是如何来规范整个…