19

认证授权:IdentityServer4 - 数据持久化

 3 years ago
source link: http://www.cnblogs.com/cwsheng/p/13737196.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言:

前面的文章中IdentityServer4 配置内容都存储到内存中,本篇文章开始把配置信息存储到数据库中;本篇文章继续基于 github的代码 来实现配置数据持久化到MySQL中

一、基于EFCore持久化IdentityServer数据

1、数据库上下文(DbContext )

在前面使用IDS4时,配置的一些基础:如Api资源、客户端等数据;以及在使用过程中授权后发放的token、授权、授权码等操作数据。如果持久化如何处理呢?IDS4已经提供了对应的方式

    • ConfigurationDbContext

主要负责数据库对客户端、标识资源、Api资源和CORS等的配置存储

    • PersistedGrantDbContext 

主要存储操作数据,如:授权码、访问令牌、刷新令牌等相关操作数据

2、在 cz.IdentityServer 中添加Nuget包:IdentityServer4.EntityFramework以及EF相关包

Install-Package IdentityServer4.EntityFramework
Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Tools

Install-Package Microsoft.EntityFrameworkCore.Design

Install-Package Pomelo.EntityFrameworkCore.MySql 

3、修改Startup文件中ConfigureServices方法中IdentityServer4配置内容如下:

public class Startup
{

    private IConfiguration _configuration;
    public Startup(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        services.Configure<CookiePolicyOptions>(options =>
        {
            options.MinimumSameSitePolicy = SameSiteMode.Strict;
        });
     //获取连接串
        string connString = _configuration.GetConnectionString("Default");
     string migrationsAssembly = Assembly.GetEntryAssembly().GetName().Name;
        //添加IdentityServer服务
        services.AddIdentityServer()
            //添加这配置数据(客户端、资源)
            .AddConfigurationStore(opt =>
            {
                opt.ConfigureDbContext = c =>
                {
                    c.UseMySql(connString, sql => sql.MigrationsAssembly(migrationsAssembly));
                };
            })
            //添加操作数据(codes、tokens、consents)
            .AddOperationalStore(opt =>
            {
                opt.ConfigureDbContext = c =>
                {
                    c.UseMySql(connString, sql => sql.MigrationsAssembly(migrationsAssembly));
                };
                //token自动清理
                opt.EnableTokenCleanup = true;
                ////token自动清理间隔:默认1H
                //opt.TokenCleanupInterval=3600;
                ////token自动清理每次数量
                //opt.TokenCleanupBatchSize = 100;
            })
        //用户默认依旧采用内存用户,可用Identity替换
       .AddTestUsers(InMemoryConfig.Users().ToList());
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      //初始化数据(内容后面描述)
     SeedData.InitData(app);
if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseStaticFiles();
        app.UseCookiePolicy();
        app.UseIdentityServer();

        app.UseAuthentication();
        //使用默认UI,必须添加
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

4、迁移数据

迁移方式有多种方式:

1、打开包控制台,执行以下命令:

1 add-migration InitialPersistedGrantDb -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb 
2 add-migration InitialConfigurationDb -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb
3 update-database -c PersistedGrantDbContext   
4 update-database -c ConfigurationDbContext   

2、在项目路径中执行命令行:

1 dotnet ef migrations add InitialPersistedGrantDb -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb
2 dotnet ef migrations add InitialConfigurationDb -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb
3 dotnet ef database update -c PersistedGrantDbContext 
4 dotnet ef database update -c ConfigurationDbContext  

二、数据表含义

数据结构迁移完成我们来看下创建了那些表:

qEVBbqr.png!mobile

根据不同的数据库上下文划分如下图:

I7j6N3M.png!mobile

三、初始化数据

1、创建文件SeedData.cs文件用于初始化基础数据:

public class SeedData
{
    public static void InitData(IApplicationBuilder serviceProvider)
    {
        Console.WriteLine("开始创建初始化数据...");
        using (var scope = serviceProvider.ApplicationServices.CreateScope())
        {
            scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
            {
                var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
                context.Database.Migrate();
                EnsureSeedData(context);
            }
        }
        Console.WriteLine("初始化数据创建完成.");
    }

    private static void EnsureSeedData(ConfigurationDbContext context)
    {
        if (!context.Clients.Any())
        {
            Console.WriteLine("Clients 正在初始化");
            foreach (var client in InMemoryConfig.GetClients())
            {
                context.Clients.Add(client.ToEntity());
            }
            context.SaveChanges();
        }

        if (!context.IdentityResources.Any())
        {
            Console.WriteLine("IdentityResources 正在初始化");
            foreach (var resource in InMemoryConfig.GetIdentityResources())
            {
                context.IdentityResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }

        if (!context.ApiResources.Any())
        {
            Console.WriteLine("ApiResources 正在初始化");
            foreach (var resource in InMemoryConfig.GetApiResources())
            {
                context.ApiResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }

        if (!context.ApiScopes.Any())
        {
            Console.WriteLine("ApiScopes 正在初始化");
            foreach (var resource in InMemoryConfig.GetApiScopes())
            {
                context.ApiScopes.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }
    }
}

2、并在Startup文件中添加:

 //初始化数据(内容后面描述)
SeedData.InitData(app);

程序运行如下:

YfE7F3I.png!mobile

3、初始化主要数据结果如下图:

ayIZFv.png!mobile

4、运行效果同上一篇文章效果相同

v6BvU36.png!mobile

四、其他

本篇主要介绍了简单使用IdentityServer4.EntityFramework持久化存储相关配置数据和操作数据;本篇中用户信息未持久化存储未介绍,因为IdentityServer4本就支持了接入其他认证方式,如 : NetCore 官方的 Identity,可以快速实现用户管理。

Github: https://github.com/cwsheng/IdentityServer.Demo


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK