IdentityServer4 中文文檔 -16- (快速入門)使用 EntityFramework Core 存儲配置數據
原文:http://docs.identityserver.io/en/release/quickstarts/8_entity_framework.html
上一篇:IdentityServer4 中文文檔 -15- (快速入門)添加 JavaScript 客戶端
IdentityServer 是為可擴展性設計的,其中一個擴展點是其所需數據的存儲機制。該快速入門展示了如何配置 IdentityServer 以使用 EntityFramework(EF)作為其數據存儲機制(取代目前為止我們一直使用的內存實現)。
IdentityServer4.EntityFramework
我們將移動到數據庫的數據有兩種,第一種是配置數據(資源 resources 和客戶端 client 定義數據)。第二種是 IdentityServer 運行時產生的操作數據。這些存儲庫都是基於接口建模的,並且我們在 IdentityServer4.EntityFramework
NuGet 程序包中為這些接口提供了一套 EF 實現。
我們從添加 IdentityServer4.EntityFramework
NuGet 程序包的引用到 IdentityServer 項目中開始(請使用“1.0.1”以上版本的程序包):
添加 SqlServer
鑒於 EF 的靈活性,你現在可以使用任何 EF 支持的數據庫。在該快速入門中我們將使用 Visual Studio 自帶的 SqlServer LocalDb 版。
為了添加 SqlServer,我們需要多一些 NeGet 程序包。
添加 Microsoft.EntityFrameworkCore.SqlServer
程序包:
添加 Microsoft.EntityFrameworkCore.Tools
程序包:
接下來,我們要添加一些命令行工具(更多細節請點擊這里) —— 很不幸,你必須要通過手動編輯 .csproj 文件來實現這些。你可以在 IdentityServer 項目上點擊鼠標右鍵並選擇“編輯 QuickstartIdentityServer.csproj”以手動修改 .csproj 文件:
然后添加以下片段到 元素標簽之前:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
</ItemGroup>
其最終看起來是這樣的:
保存並關閉該文件。為了驗證你已經安裝了工具屬性,你可以在項目文件目錄下打開命令提示符並運行 dotnet ef
命令。運行結果看起來大概是這樣的:
配置存儲
下一個步驟是替換當前在 Startup.cs 的 ConfigureServices
方法中調用的 AddInMemoryClients
、AddInMemoryIdentityResources
和 AddInMemoryApiResources
。我們將用以下代碼替換它們:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var connectionString = @"server=(localdb)\mssqllocaldb;database=IdentityServer4.Quickstart.EntityFramework;trusted_connection=yes";
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
// 配置使用內存存儲用戶信息,但使用 EF 存儲客戶端和資源信息。
services.AddIdentityServer()
.AddTemporarySigningCredential()
.AddTestUsers(Config.GetUsers())
.AddConfigurationStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)))
.AddOperationalStore(builder =>
builder.UseSqlServer(connectionString, options =>
options.MigrationsAssembly(migrationsAssembly)));
}
上述代碼將連接字符串直接硬編碼到了代碼里面,你可以根據需要進行更改。還有,調用 AddConfigurationStore
和 AddOperationalStore
其實是為了將 EF 的存儲實現注冊到系統中。
傳遞給這些 API 的 “builder” 回調函數是 EF 的機制,這種機制允許你為上述兩個存儲實現的 DbContext
配置對應的 DbContextOptionsBuilder
—— 這涉及到你將如何使用數據庫提供程序來裝配 DbContext 類型的實例。這里通過調用 UseSqlServer
來使用 SqlServer。你也可以看得出來,這里就是提供數據庫連接字符串的地方。
UseSqlServer
方法中的 “options” 回調方法則是用來配置 EF 數據遷移定義所在的程序集的。EF 需要使用數據遷移來為數據庫定義相應的架構。
注意:定義這些遷移應該是你的宿主應用程序的職責,因為它們是特定於你的數據庫及其提供程序。
我們接下來將添加數據遷移。
添加數據遷移
為了創建遷移,你需要打開命令提示符並定位到 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
運行結果看起來應該是這樣的:
初始化數據庫
現在我們有了數據遷移,我們可以編寫代碼來從數據遷移創建數據庫了。我們還將使用之前的快速入門中定義的內存配置數據作為種子來初始化數據庫。
在 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)
{
// 人為初始化數據庫
InitializeDatabase(app);
// 其它原有的代碼
// ...
}
現在,如果你運行 IdentityServer 項目,應該會創建數據庫並使用之前定義的配置數據初始化它。你應該能夠使用 SqlServer Management Studio 或 Visual Studio 連接和檢查數據:
運行客戶端應用程序
現在你應該能夠運行所有現有的客戶端應用程序並登陸、獲取令牌以及調用API了 —— 這些都是基於數據庫配置的。