IdentityServer4(五):使用EF Core持久化配置和操作數據

使用Entity Framework Core持久化配置和操作數據

前文中,我們所有的IdentityServer4配置都是在代碼中寫死的,在實際的生產環境中肯定不能這麼處理。本篇將使用Entity Framework Core持久化配置和存儲操作數據。

IdentityServer4.EntityFramework

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

  • ConfigurationDbContext
    用於配置數據,如clients,resources和scopes。
  • PersistedGrantDbContext
    用於臨時操作數據,如授權代碼和刷新令牌

配置Stores

必要的nuget

Install-Package IdentityServer4.EntityFramework -Version 3.1.0
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.1.0

我們在前文代碼的基礎上進行修改,刪除了Config中寫死的配置,添加了AddConfigurationStore()AddOperationalStore(),並使用SqlServer作爲存儲庫。

public void ConfigureServices(IServiceCollection services)
{
    var connectionString = Configuration.GetConnectionString("DefaultConnection");
    var builder = services.AddIdentityServer()
        .AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = builder =>
            {
                builder.UseSqlServer(connectionString);
            };
        })
        .AddOperationalStore(options =>
        {
            options.ConfigureDbContext = builder =>
            {
                builder.UseSqlServer(connectionString);
            };
        })
        .AddTestUsers(TestUsers.Users); ;
    builder.AddDeveloperSigningCredential();
    services.AddControllersWithViews();
}

appsettings.json中的配置

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=IDC;User ID=sa;Password=123456;"
  }
}

添加數據庫遷移

執行遷移命令

add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
add-migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb

可以看到,已成功將遷移代碼保存到:~/Data/Migrations/IdentityServer
在這裏插入圖片描述

播種數據

我們新建一個SeedData,提供一個public方法EnsureSeedData(),將我們此前寫死在config中的配置信息持久化到SQL Server中。

public class SeedData
{
    public static void EnsureSeedData(string conncetionString)
    {
        var migtationAssembly = typeof(SeedData).GetTypeInfo().Assembly.GetName().Name;
        var service = new ServiceCollection();
        service.AddConfigurationDbContext(options =>
        {
            options.ConfigureDbContext = db => db.UseSqlServer(conncetionString, 
            	sql => sql.MigrationsAssembly(migtationAssembly));
        });
        service.AddOperationalDbContext(options =>
        {
            options.ConfigureDbContext = db => db.UseSqlServer(conncetionString, 
            	sql => sql.MigrationsAssembly(migtationAssembly));
        });

        var serviceProvider = service.BuildServiceProvider();

        using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            scope.ServiceProvider.GetService<PersistedGrantDbContext>().Database.Migrate();

            var context = scope.ServiceProvider.GetService<ConfigurationDbContext>();
            context.Database.Migrate();
            EnsureSeedData(context);
        }
    }

    private static void EnsureSeedData(IConfigurationDbContext context)
    {
        if (!context.Clients.Any())
        {
            foreach (var client in Config.Clients)
                context.Clients.Add(client.ToEntity());
            context.SaveChanges();
        }
        if (!context.ApiResources.Any())
        {
            foreach (var api in Config.Apis)
                context.ApiResources.Add(api.ToEntity());
           context.SaveChanges();
        }

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

在程序入口調用

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var config = host.Services.GetRequiredService<IConfiguration>();
    var connectionString = config.GetConnectionString("DefaultConnection");
    SeedData.EnsureSeedData(connectionString);
    
    host.Run();
}

當我們運行程序時,可以看到成功生成了數據庫和相應的數據表
在這裏插入圖片描述

配置信息也已經寫入
在這裏插入圖片描述

我們可以進行一次登錄,然後查看PersistedGrants中的數據,可以看到
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章