在 使用 ASP.NET Core Identity 的 IdentityServer4 授权服务器 中,IdentityServer4
使用的是内存数据,不方便灵活,这次要把 IdentityServer4
的数据也保存到数据库中。
添加 IdentityServer4.EntityFramework
IdentityServer4
有两种类型的数据需要保存数据库中。第一是配置数据(资源和客户端),第二个是 IdentityServer
在使用时产生的操作数据(令牌,代码和同意)。这些存储使用接口建模, Nuget包中的 IdentityServer4.EntityFramework
提供这些接口的EF实现。
添加 IdentityServer4.EntityFramework 包
修改 Startup.cs
在 Startup.cs
的 ConfigureServices
方法中添加以及修改以下代码:
var connectionString = Configuration.GetConnectionString("DefaultConnection"); var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; services.AddIdentityServer() .AddDeveloperSigningCredential() //.AddInMemoryPersistedGrants() //.AddInMemoryIdentityResources(Config.GetIdentityResources()) //.AddInMemoryApiResources(Config.GetApiResources()) //.AddInMemoryClients(Config.GetClients()) .AddConfigurationStore(options => { options.ConfigureDbContext = builder => builder.UseMysqL(connectionString,sql => sql.MigrationsAssembly(migrationsAssembly)); }) .AddOperationalStore(options => { options.ConfigureDbContext = builder => builder.UseMysqL(connectionString,sql => sql.MigrationsAssembly(migrationsAssembly)); // this enables automatic token cleanup. this is optional. options.EnableTokenCleanup = true; options.TokenCleanupInterval = 30; }) .AddAspNetIdentity<ApplicationUser>();
添加迁移
在项目目录中打开命令提示符。在命令提示符下运行以下两个命令,一个是为了IdentityServer的配置,另一个是为了持久化授权:
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
注意事项:Ubuntu Server 16.04 自带源安装的是
MariaDB 10.0
,执行第一个命令的时候会出现错误,请参考 安装 MariaDB 及远程连接设置 安装MariaDB 10.3
或以上版本 ,以便能顺利执行这两个命令。
初始化数据库
进行了迁移后,可以编写代码来从迁移中创建数据库。还可以将之前定义的内存配置数据来为数据库设定种子。在 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.GetClients()) { context.Clients.Add(client.ToEntity()); } context.SaveChanges(); } if (!context.IdentityResources.Any()) { foreach (var resource in Config.GetIdentityResources()) { context.IdentityResources.Add(resource.ToEntity()); } context.SaveChanges(); } if (!context.ApiResources.Any()) { foreach (var resource in Config.GetApiResources()) { context.ApiResources.Add(resource.ToEntity()); } context.SaveChanges(); } } }
public void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerFactory) { // this will do the initial DB population InitializeDatabase(app); // the rest of the code that was already here // ... }
再次运行程序,就可以将数据保存到数据库中了,我们可以通过数据库的客户端打开并看到写入到里面的内容: