您的位置:首页 > Web前端 > React

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

2022-04-14 14:55 1391 查看

##一、前言 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)

####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

数据库表、ER关系图 ####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();
}
}
}

调用代码放这里,认证服务启动时初始化,之前内存模式配置持久化到数据库 ####6、修改登录、注销代码**

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

##三、效果图 **可以看到我们必须要用新密码WinterSir123!才能登录,匹配是已经持久化数据库的信息 ##四、前任栽树,后人乘凉 https://zhuanlan.zhihu.com/p/352497277 ##五、代码已上传 https://github.com/WinterSir/IdentityServer4.GrantTypesDemo

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: