(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化

  • (十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化已关闭评论
  • 215 次浏览
  • A+
所属分类:.NET技术
摘要

IdentityServer配合EFCore持久化,框架已经为我们准备了两个上下文:用户持久化可以自定义一套逻辑,But,我们直接用微软的Identity,再新建一个用户上下文:


一、前言

IdentityServer配合EFCore持久化,框架已经为我们准备了两个上下文:

  • ConfigurationDbContext:配置数据(资源、客户端、身份等)
  • PersistedGrantDbContext:操作数据(授权码、访问令牌、刷新令牌等)

用户持久化可以自定义一套逻辑,But,我们直接用微软的Identity,再新建一个用户上下文:

  • ApplicationDbContext:用户数据(用户、角色等)

二、持久化

1、新建认证服务

新建一个MVC工程,目录结构跟上篇内存化大致一样,IdentityServer4.Persistence安装所需包:

  • IdentityServer4
  • IdentityServer4.EntityFramework
  • Microsoft.EntityFrameworkCore.Tools
  • Npgsql.EntityFrameworkCore.PostgreSQL(PostgreSQL)
  • IdentityServer4.AspNetIdentity(IdentityServer4支持微软Indentity)
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore(Identity支持EF)

(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化

2、新建用户上下文

//IdentityUser实际肯定是需要拓展的,还有一些自定义等功能,Demo这儿就不费劲了,随后要挪到正式的环境,用到再细说 public class ApplicationDbContext : IdentityDbContext<IdentityUser> {     public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)         : base(options)     {     }      protected override void OnModelCreating(ModelBuilder builder)     {         base.OnModelCreating(builder);     } } 

3、Startup.cs 配置持久化

public void ConfigureServices(IServiceCollection services) {     services.AddControllersWithViews();      //读取数据库连接     var connectionString = Configuration.GetSection("DB").Value;     if (connectionString == "")     {         throw new Exception("数据库配置异常");     }      /**********************************IdentityServer4持久化配置**********************************/      var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;      //添加用户数据上下文 ApplicationDbContext     services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(connectionString));     services.AddIdentity<IdentityUser, IdentityRole>()         .AddEntityFrameworkStores<ApplicationDbContext>()         .AddDefaultTokenProviders();      //添加配置数据上下文 ConfigurationDbContext、操作数据上下文 PersistedGrantDbContext、用户持久化     var builder = services.AddIdentityServer()     .AddConfigurationStore(options =>     {         options.ConfigureDbContext = builder =>         {             builder.UseNpgsql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));         };     })     .AddOperationalStore(options =>     {         options.ConfigureDbContext = builder =>         {             builder.UseNpgsql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));         };         //token配置         options.EnableTokenCleanup = true;         options.TokenCleanupInterval = 30;     })     .AddAspNetIdentity<IdentityUser>()     .AddDeveloperSigningCredential(); } 

4、迁移到数据库

程序包管理器控制台,依次输入一下命令回车:

  • add-migration InitialPersisted -c PersistedGrantDbContext -o Migrations/Persisted
  • update-database -Context PersistedGrantDbContext
  • add-migration InitialConfiguration -c ConfigurationDbContext -o Migrations/Configuration
  • update-database -Context ConfigurationDbContext
  • add-migration InitialApplication -c ApplicationDbContext -o Migrations/Application
  • update-database -Context ApplicationDbContext

(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化数据库表、ER关系图(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化

5、初始化种子数据

新建SeedData.cs,初始化种子数据,使用之前在InMemoryConfig.cs配置好的内存数据

public class SeedData {     public static void InitData(IApplicationBuilder serviceProvider)     {         using (var scope = serviceProvider.ApplicationServices.CreateScope())         {             //初始化种子数据:配置、资源、客户端等             scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();             {                 var context = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();                 context.Database.Migrate();                 InitSeedData(context);             }             //初始化种子数据:用户             {                 var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();                 context.Database.Migrate();                 var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();                 foreach (var user in InMemoryConfig.GetTestUser())                 {                     var find = userManager.FindByNameAsync(user.Username).Result;                     if (find == null)                     {                         IdentityUser u = new IdentityUser() { UserName = user.Username };                         //密码格式严格(至少一个非字母字符、至少一位0-9数字)                         var ret = userManager.CreateAsync(u, "WinterSir123!").Result;                         if (ret.Succeeded)                         {                             userManager.AddClaimsAsync(u, user.Claims);                         }                     }                 }             }         }     }     private static void InitSeedData(ConfigurationDbContext context)     {         if (!context.Clients.Any())         {             foreach (var client in InMemoryConfig.GetClients())             {                 context.Clients.Add(client.ToEntity());             }             context.SaveChanges();         }          if (!context.IdentityResources.Any())         {             foreach (var resource in InMemoryConfig.IdentityResources)             {                 context.IdentityResources.Add(resource.ToEntity());             }             context.SaveChanges();         }          if (!context.ApiResources.Any())         {             foreach (var resource in InMemoryConfig.GetApiResources())             {                 context.ApiResources.Add(resource.ToEntity());             }             context.SaveChanges();         }          if (!context.ApiScopes.Any())         {             foreach (var resource in InMemoryConfig.GetApiScopes())             {                 context.ApiScopes.Add(resource.ToEntity());             }             context.SaveChanges();         }     } } 

调用代码放这里,认证服务启动时初始化,之前内存模式配置持久化到数据库
(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化

6、修改登录、注销代码**

(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化

其实我也没弄白为啥要改登录那块,一般情况都是用框架原生提供的方法才对,百度谷歌不得其解,大佬可以指点一下

(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化

三、效果图

**可以看到我们必须要用新密码WinterSir123!才能登录,匹配是已经持久化数据库的信息
(十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化

四、前任栽树,后人乘凉

https://zhuanlan.zhihu.com/p/352497277

五、代码已上传

https://github.com/WinterSir/IdentityServer4.GrantTypesDemo