1. 程式人生 > >使用 ASP.NET Core Identity 的 IdentityServer4 授權服務器(二)

使用 ASP.NET Core Identity 的 IdentityServer4 授權服務器(二)

length 字段 dbm dconf logs 字段長度 database asp using

在 使用 ASP.NET Core Identity 的 IdentityServer4 授權服務器(1) 中,IdentityServer4 使用的是內存數據,不方便靈活,這次要把 IdentityServer4 的數據也保存到數據庫中。

添加 IdentityServer4.EntityFramework

IdentityServer4 有兩種類型的數據需要保存數據庫中。第一是配置數據(資源和客戶端)。第二個是 IdentityServer 在使用時產生的操作數據(令牌,代碼和同意)。這些存儲使用接口建模, Nuget包中的 IdentityServer4.EntityFramework 提供這些接口的EF實現。
添加 IdentityServer4.EntityFramework


技術分享圖片

修改 Startup.cs

Startup.csConfigureServices方法中添加以及修改以下代碼:

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

特別註意事項:使用 MariaDBMySQL 數據庫時,執行完第一個命令之後,在 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 授權服務器(二)