IdentityServer旨在實現可擴展性,其中一個可擴展點是用於IdentityServer所需數據的存儲機制。本快速入門展示瞭如何配置IdentityServer以使用EntityFramework Core(EF)作為此數據的存儲機制(而不是使用我們迄今為止使用的記憶體中實現)。 註意 除了手 ...
IdentityServer旨在實現可擴展性,其中一個可擴展點是用於IdentityServer所需數據的存儲機制。本快速入門展示瞭如何配置IdentityServer以使用EntityFramework Core(EF)作為此數據的存儲機制(而不是使用我們迄今為止使用的記憶體中實現)。
註意
除了手動配置EF支持外,還有一個IdentityServer模板可用於創建具有EF支持的新項目。使用創建它。有關更多信息,請參見此處dotnet new is4ef
15.1 IdentityServer4.EntityFramework
我們要移動到資料庫有兩種類型的數據:
- 配置數據
- 運營數據
配置數據是有關資源和客戶端的配置信息。操作數據是IdentityServer在使用時生成的信息,例如令牌,代碼和同意。這些存儲使用介面建模,我們在IdentityServer4.EntityFramework.Storage
Nuget包中提供這些介面的EF實現。
註冊我們的EF實現的擴展方法包含在IdentityServer4.EntityFramework Nuget包中(引用IdentityServer4.EntityFramework.Storage
)。立即從IdentityServer項目添加對IdentityServer4.EntityFramework
Nuget包的引用:
cd quickstart/src/IdentityServer
dotnet add package IdentityServer4.EntityFramework
15.2 使用的SqlServer
鑒於EF的靈活性,您可以使用任何EF支持的資料庫。對於本快速入門,我們將使用Visual Studio附帶的SQLD的LocalDb版本。
15.3 資料庫架構更改和使用EF遷移
該IdentityServer4.EntityFramework.Storage
包中包含從IdentityServer的模型映射實體類。作為IdentityServer模型變化,所以會在實體類IdentityServer4.EntityFramework.Storage
。當您使用IdentityServer4.EntityFramework.Storage
並隨著時間的推移升級時,您將負責自己的資料庫架構以及實體類更改時該架構所需的更改。管理這些更改的一種方法是使用EF遷移,此快速入門將顯示如何完成此操作。如果遷移不是您的首選項,那麼您可以以任何您認為合適的方式管理架構更改。
註意
為IdentityServer4.EntityFramework.Storage
中的實體維護SqlServer的最新SQL腳本。他們就在這裡。
15.4 配置存儲
接下來的步驟是,以取代當前AddInMemoryClients
,AddInMemoryIdentityResources
和AddInMemoryApiResources
在在Startup.cs方法ConfigureServices
。我們將使用以下代碼替換它們:
const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=IdentityServer4.Quickstart.EntityFramework-2.0.0;trusted_connection=yes;";
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddTestUsers(Config.GetUsers())
// this adds the config data from DB (clients, resources)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b =>
b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b =>
b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
});
您可能需要將這些命名空間添加到文件中:
using Microsoft.EntityFrameworkCore;
using System.Reflection;
上面的代碼是對連接字元串進行硬編碼,如果您願意,您可以隨意更改。
AddConfigurationStore
和AddOperationalStore
註冊EF支持的存儲實現。
在添加存儲的調用內部,ConfigureDbContext
屬性的賦值註冊委托以配置資料庫提供程式DbContextOptionsBuilder
。在這種情況下,我們調用UseSqlServer
註冊SQLServer。您也可以看出,這是使用連接字元串的位置。
最後,假設將使用EF遷移(至少對於此快速入門),調用將MigrationsAssembly
用於通知EF將包含遷移代碼的主機項目(這是必需的,因為它與包含DbContext
類的程式集不同)。
我們接下來會添加遷移。
15.5 添加遷移
要創建遷移,請在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
您現在應該在項目中看到~/Data/Migrations/IdentityServer文件夾。其中包含新創建的遷移的代碼。
15.6 初始化資料庫
現在我們已經進行了遷移,我們可以編寫代碼來從遷移中創建資料庫。我們還將使用我們在之前的快速入門中定義的記憶體配置數據來為資料庫設定種子。
註意
本快速入門中使用的方法用於簡化IdentityServer的啟動和運行。您應該設計適合您的體繫結構的資料庫創建和維護策略。
在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.GetApis())
{
context.ApiResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
}
}
上面的代碼可能需要將這些命名空間添加到您的文件中:
using System.Linq;
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;
然後我們可以從Configure
方法中調用它:
public void Configure(IApplicationBuilder app)
{
// this will do the initial DB population
InitializeDatabase(app);
// the rest of the code that was already here
// ...
}
現在,如果運行IdentityServer項目,則應創建資料庫並使用快速入門配置數據進行種子設定。您應該能夠使用SQL Server Management Studio或Visual Studio來連接和檢查數據。
註意
上面的InitializeDatabase
輔助API可以方便地為資料庫設定種子,但是這種方法並不適合每次運行應用程式時執行。填充資料庫後,請考慮刪除對API的調用。
15.7 運行客戶端應用程式
您現在應該能夠運行任何現有的客戶端應用程式並登錄,獲取令牌並調用API - 所有這些都基於資料庫配置。
註意
本節中的代碼仍然依賴於Config.cs
及其虛構用戶Alice和Bob。如果您的用戶列表很簡短且靜態,則調整後的Config.cs
版本可能就足夠了,但您可能希望在資料庫中動態管理更大且更流暢的用戶列表。ASP.NET Identity是一個需要考慮的選項,下一節的快速入門列出了此解決方案的示例實現。