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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容