认证授权:IdentityServer4 – 数据持久化
- 2020 年 10 月 6 日
- 笔记
- IdentityServer4, 授权, 认证
前言:
前面的文章中IdentityServer4 配置内容都存储到内存中,本篇文章开始把配置信息存储到数据库中;本篇文章继续基于github的代码来实现配置数据持久化到MySQL中
一、基于EFCore持久化IdentityServer数据
1、数据库上下文(DbContext )
在前面使用IDS4时,配置的一些基础:如Api资源、客户端等数据;以及在使用过程中授权后发放的token、授权、授权码等操作数据。如果持久化如何处理呢?IDS4已经提供了对应的方式
-
- ConfigurationDbContext
主要负责数据库对客户端、标识资源、Api资源和CORS等的配置存储
-
- PersistedGrantDbContext
主要存储操作数据,如:授权码、访问令牌、刷新令牌等相关操作数据
2、在cz.IdentityServer中添加Nuget包:IdentityServer4.EntityFramework以及EF相关包
Install-Package IdentityServer4.EntityFramework
Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Pomelo.EntityFrameworkCore.MySql
3、修改Startup文件中ConfigureServices方法中IdentityServer4配置内容如下:
public class Startup { private IConfiguration _configuration; public Startup(IConfiguration configuration) { _configuration = configuration; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit //go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.Configure<CookiePolicyOptions>(options => { options.MinimumSameSitePolicy = SameSiteMode.Strict; }); //获取连接串 string connString = _configuration.GetConnectionString("Default");
string migrationsAssembly = Assembly.GetEntryAssembly().GetName().Name; //添加IdentityServer服务 services.AddIdentityServer() //添加这配置数据(客户端、资源) .AddConfigurationStore(opt => { opt.ConfigureDbContext = c => { c.UseMySql(connString, sql => sql.MigrationsAssembly(migrationsAssembly)); }; }) //添加操作数据(codes、tokens、consents) .AddOperationalStore(opt => { opt.ConfigureDbContext = c => { c.UseMySql(connString, sql => sql.MigrationsAssembly(migrationsAssembly)); }; //token自动清理 opt.EnableTokenCleanup = true; ////token自动清理间隔:默认1H //opt.TokenCleanupInterval=3600; ////token自动清理每次数量 //opt.TokenCleanupBatchSize = 100; })
//用户默认依旧采用内存用户,可用Identity替换
.AddTestUsers(InMemoryConfig.Users().ToList()); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
//初始化数据(内容后面描述)
SeedData.InitData(app);
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseIdentityServer(); app.UseAuthentication(); //使用默认UI,必须添加 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } }
4、迁移数据
迁移方式有多种方式:
1、打开包控制台,执行以下命令:
1 add-migration InitialPersistedGrantDb -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb 2 add-migration InitialConfigurationDb -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb 3 update-database -c PersistedGrantDbContext 4 update-database -c ConfigurationDbContext
2、在项目路径中执行命令行:
1 dotnet ef migrations add InitialPersistedGrantDb -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb 2 dotnet ef migrations add InitialConfigurationDb -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb
3 dotnet ef database update -c PersistedGrantDbContext
4 dotnet ef database update -c ConfigurationDbContext
二、数据表含义
数据结构迁移完成我们来看下创建了那些表:
根据不同的数据库上下文划分如下图:
三、初始化数据
1、创建文件SeedData.cs文件用于初始化基础数据:
public class SeedData { public static void InitData(IApplicationBuilder serviceProvider) { Console.WriteLine("开始创建初始化数据..."); using (var scope = serviceProvider.ApplicationServices.CreateScope()) { scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate(); { var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); context.Database.Migrate(); EnsureSeedData(context); } } Console.WriteLine("初始化数据创建完成."); } private static void EnsureSeedData(ConfigurationDbContext context) { if (!context.Clients.Any()) { Console.WriteLine("Clients 正在初始化"); foreach (var client in InMemoryConfig.GetClients()) { context.Clients.Add(client.ToEntity()); } context.SaveChanges(); } if (!context.IdentityResources.Any()) { Console.WriteLine("IdentityResources 正在初始化"); foreach (var resource in InMemoryConfig.GetIdentityResources()) { context.IdentityResources.Add(resource.ToEntity()); } context.SaveChanges(); } if (!context.ApiResources.Any()) { Console.WriteLine("ApiResources 正在初始化"); foreach (var resource in InMemoryConfig.GetApiResources()) { context.ApiResources.Add(resource.ToEntity()); } context.SaveChanges(); } if (!context.ApiScopes.Any()) { Console.WriteLine("ApiScopes 正在初始化"); foreach (var resource in InMemoryConfig.GetApiScopes()) { context.ApiScopes.Add(resource.ToEntity()); } context.SaveChanges(); } } }
2、并在Startup文件中添加:
//初始化数据(内容后面描述) SeedData.InitData(app);
程序运行如下:
3、初始化主要数据结果如下图:
4、运行效果同上一篇文章效果相同
四、其他
本篇主要介绍了简单使用IdentityServer4.EntityFramework持久化存储相关配置数据和操作数据;本篇中用户信息未持久化存储未介绍,因为IdentityServer4本就支持了接入其他认证方式,如 : NetCore 官方的 Identity,可以快速实现用户管理。
Github://github.com/cwsheng/IdentityServer.Demo