IdentityServer4 快速入門7:使用EntityFramework Core進行配置和運營數據

在之前的快速入門中,我們用代碼創建了客戶和范圍數據。 啟動時,IdentityServer將此配置數據加載到內存中。 如果要修改此配置數據,則必須停止并啟動IdentityServer。

IdentityServer還會生成臨時數據,例如授權碼,同意選擇和刷新令牌。 默認情況下,它們也存儲在內存中。

要將這些數據移入在重啟之間和多個IdentityServer實例之間保持持久性的數據庫中,我們可以使用IdentityServer4 Entity Framework。

Note
除了手動配置EF支持外,還有一個IdentityServer模板,可使用dotnet new is4ef創建具有EF支持的新項目。

IdentityServer4.EntityFramework

IdentityServer4.EntityFramework使用以下DbContext實現所需的存儲和服務:

  • ConfigurationDbContext-用于配置數據,例如客戶端,資源和范圍
  • PersistedGrantDbContext-用于臨時操作數據,例如授權碼和刷新令牌這些上下文適用于任何與Entity Framework Core兼容的關系數據庫。

您可以在IdentityServer4.EntityFramework.Storage nuget包中找到這些上下文,它們的實體以及使用它們的IdentityServer4存儲。

您可以在IdentityServer4.EntityFramework中的IdentityServer中找到將其注冊的擴展方法,我們現在將這樣做:

dotnet add package IdentityServer4.EntityFramework

使用SqlServer

對于本快速入門,我們將使用Visual Studio附帶的SQLServer LocalDb版本。 要將SQL Server支持添加到我們的IdentityServer項目中,您需要以下nuget軟件包:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

# How to setup Identity Server 4 with MySQL

數據庫架構更改和使用EF遷移

IdentityServer4.EntityFramework.Storage程序包包含從IdentityServer的模型映射的實體類。 隨著IdentityServer的模型更改,IdentityServer4.EntityFramework.Storage中的實體類也會更改。 當您使用IdentityServer4.EntityFramework.Storage并隨時間進行升級時,您將負責數據庫架構以及隨著實體類的更改而對該架構進行的必要更改。 管理這些更改的一種方法是使用 EF遷移,這就是本快速入門中將使用的方法。 如果您不希望進行遷移,則可以按照自己認為合適的任何方式來管理模式更改。

注意
您可以在IdentityServer4.EntityFramework.Storage存儲庫中找到SqlServer的最新SQL腳本。

配置倉儲

要開始使用這些存儲,您需要使用AddConfigurationStoreAddOperationalStore替換Startup.cs中ConfigureServices方法中對AddInMemoryClientsAddInMemoryIdentityResourcesAddInMemoryApiResourcesAddInMemoryPersistedGrants的所有現有調用。

這些方法每個都需要一個DbContextOptionsBuilder,這意味著您的代碼將如下所示:

var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=IdentityServer4.Quickstart.EntityFramework-3.0.0;trusted_connection=yes;";

services.AddIdentityServer()
    .AddTestUsers(TestUsers.Users)
    .AddConfigurationStore(options =>
    {
        options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
            sql => sql.MigrationsAssembly(migrationsAssembly));
    })
    .AddOperationalStore(options =>
    {
        options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
            sql => sql.MigrationsAssembly(migrationsAssembly));
    });

您可能需要將以下名稱空間添加到文件中:

using Microsoft.EntityFrameworkCore;
using System.Reflection;

因為在此快速入門中我們正在使用EF遷移,所以對MigrationsAssembly的調用用于通知Entity Framework宿主項目將包含遷移代碼。 這是必需的,因為宿主項目與包含DbContext類的項目不在同一個程序集中。

添加遷移

將IdentityServer配置為使用Entity Framework之后,我們將需要進行一些遷移。

要創建遷移,您將需要在計算機上安裝Entity Framework Core CLI,并在IdentityServer中安裝Microsoft.EntityFrameworkCore.Design nuget包:

dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design

要創建遷移,請在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文件夾,其中包含新創建的遷移的代碼。

初始化數據庫

現在我們有了遷移,我們可以編寫代碼從遷移創建數據庫。 我們還可以使用先前快速入門中已定義的內存中配置數據為數據庫添加種子。

注意
本快速入門中使用的方法用于使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.Clients)
            {
                context.Clients.Add(client.ToEntity());
            }
            context.SaveChanges();
        }

        if (!context.IdentityResources.Any())
        {
            foreach (var resource in Config.Ids)
            {
                context.IdentityResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }

        if (!context.ApiResources.Any())
        {
            foreach (var resource in Config.Apis)
            {
                context.ApiResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }
    }
}

上面的代碼可能要求您向文件中添加以下名稱空間:

using System.Linq;
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;

然后我們可以從Configure方法中調用它:

public void Configure(IApplicationBuilder app)
{
    // 這將完成初始數據庫填充
    InitializeDatabase(app);

    // 其余的代碼已經在這里
    // ...
}

現在,如果您運行IdentityServer項目,則應創建數據庫并使用快速入門配置數據播種。 您應該能夠使用SQL Server Management Studio或Visual Studio來連接和檢查數據。

image.png

注意
上面的InitializeDatabase幫助器API可以方便地為數據庫添加種子,但是這種方法并不適合每次運行應用程序時執行。 填充數據庫后,請考慮刪除對API的調用。

運行客戶端應用程序

現在,您應該能夠運行任何現有的客戶端應用程序并登錄,獲取令牌并調用API-所有這些都基于數據庫配置。

Source code here

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容