当前位置:网站首页>[one by one series] identityserver4 (VIII) uses entityframework core to persist data

[one by one series] identityserver4 (VIII) uses entityframework core to persist data

2022-06-23 19:01:00 DDGarfield

Last few , We created the client ,scope, Startup time ,IdentityServer Load the configuration data into memory , however , If we want to change the configuration , You have to stop IdentityServer, And then restart it . And IdentityServer Temporary data will also be generated during operation , Such as authorization code 、 Whether to agree with the button selection 、 as well as refresh token. By default , These are also stored in memory .

Store the above data in the database for data persistence , Easy restart across multiple IdentityServer example , This persistence , We can use IdentityServer4 Entity Framework

In addition to manual configuration EF Beyond support , One more IdentityServer Templates can be used ,dotnet new is4ef Create a support EF New projects .

IdentityServer4.EntityFrameworknuget The package implements the required storage and services , The following two are mainly used DbContexts:

  • ConfigurationDbContext - Apply to registration data , Such as client , resources ,scope wait
  • PersistedGrantDbContext - Act on temporary operation data , Such as authorization code ,refresh tokens

these context Apply to any ef core Compatible relational databases ,sqlserver,mysql.

Can be in

  • IdentityServer4.EntityFramework.Storage Found in the package context,entities,IdentityServer4 stores
  • IdentityServer4.EntityFramework Including the extension method of registration , And includes IdentityServer4.EntityFramework.Storage

1. add to nuget quote

cd .\IdentityServer\
dotnet add package IdentityServer4.EntityFramework

2. Add pair mysql Support for

dotnet add package MySql.Data.EntityFrameworkCore

3. Data migration

IdentityServer4.EntityFramework.Storage Package existence contains mappings from IdentityServer Entity class of the model , With IdentityServer Changes to the model of ,IdentityServer4.EntityFramework.Storage The entity classes in will also change , Therefore, users are required to follow the passage of time , Upgrade to use this package , This process , You need to be responsible for changing the database schema and entity classes , Make the necessary changes to the database schema . The best way is to use EF Data migration (EF migrations)

The official here only provides information for sqlserver Of sql Script , You can look at it , Let's get to know each other .

4. Reconfigure storage

stay Startup.cs

using Microsoft.EntityFrameworkCore;
using System.Reflection; // Here we use reflection 

var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

//3308 Is the host port , mapping docker mysql Container default port 3306
const string connectionString = @"Persist Security Info=False;database=IdentityServer4;server=localhost;port=3308;Connect Timeout=30;user id=root; pwd=123456";

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

Because we are IdentityServer.csproj Use in EF transfer , So by right MigrationsAssembly To tell Entity Framework Host project for (IdentityServer.csproj) Will contain migration code (the migrations code). This is necessary , Because the host project (IdentityServer.csproj) And contain DbContext Class projects , The two are in different assemblies (IdentityServer4.EntityFramework.Storage).

5. Create migration

Once the IdentityServer Configure to use Entity Framework Core, We will need to generate some migrations -migrations.

Entity Framework Core CLI

Microsoft.EntityFrameworkCore.Design nuget package

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

#cd To IdentityServer Project directory 
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb


dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb

Consider the past you shall know the future : Remember when VS Of Package Manager Console How to execute the command to create the migration ?

# First step 

Add-Migration InitialCreate

# The second step 

Update-Database

6. Initialize database

Now we have finished the migration , We can write code to migrate from -migrations Create database . We can also use the quickstart To initialize the seed for the database , Of course, this seed It is best to just execute in a debug environment .

Official tip : The main method used in this quick start is to make IdentityServer Easier to start and run . You should design a database creation and maintenance strategy that suits your architecture .

stay Startup.cs Add the following initialization method in :

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

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.IdentityResources)
            {
                context.IdentityResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }

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

public void Configure(IApplicationBuilder app)
{
    // this will do the initial DB population
    InitializeDatabase(app);

    // the rest of the code that was already here
    // ...
}

above InitializeDatabase The method can easily seed the database, But this method is not ideal to be left in every time the application is run . Once the database initialization data is populated , You can consider deleting the call to it .

7. Run the client application

This is a little simpler , Just the last command

cd src\IdentityServer
dotnet run
原网站

版权声明
本文为[DDGarfield]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206231758267530.html