在 使用 ASP.NET Core Identity 的 IdentityServer4 授权服务器(1) 中,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
特别注意事项:使用
MariaDB
或MySQL
数据库时,执行完第一个命令之后,在 VS 中打开 Data\Migrations\IdentityServer\PersistedGrantDb\PersistedGrantDbContextModelSnapshot.cs 文件,找到大概在 32 - 34 行的如以下内容:
b.Property<string>("Data")
.IsRequired()
.HasMaxLength(50000);
将 HasMaxLength(50000)
内的数字更改为HasMaxLength(20000)
,因为原来的长度 50000 超过了MySQL的字段长度。
修改完并保存后再执行第二个命令。
修改后的内容看起来象下面这个样子:
b.Property<string>("Data")
.IsRequired()
.HasMaxLength(20000);
初始化数据库
进行了迁移后,可以编写代码来从迁移中创建数据库。还可以将之前定义的内存配置数据来为数据库设定种子。在 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();
}
}
}
从 Configure
方法调用它:
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
// ...
}
再次运行程序,就可以将数据保存到数据库中了,我们可以通过数据库的客户端打开并看到写入到里面的内容:
InitializeDatabase
方法并不适合每次运行应用程序时执行,填充数据库后,请考虑删除(或注释)对它的调用。
原文地址:https://www.cnblogs.com/mahidol/p/9362673.html