使用EF Core支持的数据库来存储Identity Server4的配置
分类: IdentityServer4教程 ◆ 标签: #Asp.Net core基础 #认证 #授权 #Identity Server #OpenId Connect #OAuth2 ◆ 发布于: 2023-05-27 22:50:25

本节的源代码可以从如下位置找到:
sourcecode
我们前面的例子中在项目IdentityServer
中都是使用一个config
类来定义资源和scope, 以及客户端,但是在实际的应用中,我们可能需要更加方便的管理资源,scope以及客户端的形式,例如可以有一个界面允许客户端自己注册并生成security来使用QAuth2.0或者openIDConnect, 因此对于IdentityServer4来说我们需要一些其他的方法动态的配置这些参数。
IdentityServer4
提供EF Core的支持,从而将这些配置放到数据库中进行保存。
EF Core的支持中分为两块,一块是对于配置的保存,另外一块是对一些中间运行的数据进行保存,例如生成的key等等。
IdentityServer4.EntityFramework
在is4中我们通过包IdentityServer4.EntityFramework
来支持EF Core存储配置和运行数据的保存。
我们回到项目src\IdentityServer中, 运行如下的命令来添加包的支持:
dotnet add package IdentityServer4.EntityFramework
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
注意
关于数据库的schema
定义,您可以参考包IdentityServer4.EntityFramework.Storage
, 你可以从这个脚本找到所有的数据库定义SQLScript
配置Store
请参考如下的代码:
src\IdentityServer\Startup.cs
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=IdentityServer4.Quickstart.EntityFramework-4.0.0;trusted_connection=yes;"; services.AddIdentityServer() .AddTestUsers(TestUsers.Users) .AddConfigurationStore(options => { options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly)); }) .AddOperationalStore(options => { options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly)); }) .AddDeveloperSigningCredential();
从这部分代码可以看出我们移除了之前的通过services.AddIentityServer().AddInMemoryIdentityResources(Config.IdentityResources)
将配置和中间的变量等放入了EF Core支持的数据库中。
注意
需要在类Startup.cs
引入如下的包using Microsoft.EntityFrameworkCore; using System.Reflection;
添加数据库迁移
安装工具
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
生成数据库迁移
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
初始化数据库
我们这里直接使用之前使用config.cs
生成的数据,因此我们在这里定义一个初始化数据库的方法,改方法定义在类startup.cs中。
private void InitializeDatabase(IApplicationBuilder app) { using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) { serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate(); var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); context.Database.Migrate(); if (!context.Clients.Any()) { foreach (var client in Config.Clients) { context.Clients.Add(client.ToEntity()); } context.SaveChanges(); } if (!context.IdentityResources.Any()) { foreach (var resource in Config.IdentityResources) { context.IdentityResources.Add(resource.ToEntity()); } context.SaveChanges(); } if (!context.ApiScopes.Any()) { foreach (var resource in Config.ApiScopes) { context.ApiScopes.Add(resource.ToEntity()); } context.SaveChanges(); } } }
注意
我们需要在类Startup.cs
中添加如下的引用using System.Linq; using IdentityServer4.EntityFramework.DbContexts; using IdentityServer4.EntityFramework.Mappers;
然后在类Startup.Configure()
中调用:
public void Configure(IApplicationBuilder app) { // this will do the initial DB population InitializeDatabase(app); // the rest of the code that was already here // ... }
然后运行之前的Api, IdentityServer以及JavaScriptClient应用进行测试就可以了