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



作者:老中医2020
链接:https://www.jianshu.com/p/f9a6cde6c6d8
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2021-03-26 13:40  dreamw  阅读(367)  评论(0编辑  收藏  举报