使用 ASP.NET Core Identity 的 IdentityServer4 授權服務器(二)
在 使用 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
方法並不適合每次運行應用程序時執行,填充數據庫後,請考慮刪除(或註釋)對它的調用。
使用 ASP.NET Core Identity 的 IdentityServer4 授權服務器(二)