七台河建设网站,网络规划师含金量,有哪些网站是中国风网站,经典重庆哈喽大家周三好#xff0c;今天终于又重新开启 IdentityServer4 的落地教程了#xff0c;不多说#xff0c;既然开始了#xff0c;就要努力做好?。书接上文#xff0c;在很久之前的上篇文章《二║ 基础知识集合 项目搭建一》中#xff0c;我们简单的说了说 Identi… 哈喽大家周三好今天终于又重新开启 IdentityServer4 的落地教程了不多说既然开始了就要努力做好?。书接上文在很久之前的上篇文章《二║ 基础知识集合 项目搭建一》中我们简单的说了说 IdentityServer4 是如何调用和配置 Token 的主要是一些入门的基础知识和概念也算是第一次尝鲜了其实 Ids4 本身没有那么神秘我们只需要知道它是一个丰富的认证框架又具有很好的可扩展性核心就是如何配置某些客户端通过该授权服务来包括另一些资源服务器供用户使用。因为中间隔了很长时间了这里简单的回顾下上篇文章说了什么下边这几个小问题相信大家脑中都能很快的有一些概念至少是脸熟了如果不是很清楚请翻看上边的链接或者官网再看看1、什么是资源什么是客户端什么是令牌 2、IdentityServer4 主要是授权还是认证 3、OAuth 2.0、OpenID、OpenID Connect三者的关系 4、Ids4 依赖的 Nuget 包是什么 5、如何快速开发 UI 今天这篇文章主要是操作和探索相结合的一篇我看网上很多教程基本上是按照官网概念的知识点配合着 Github 开源地址讲解一遍知识是懂了可是要是自己开发起来还是有很多的疑惑甚至是根本走不下去我就从初学者的立场出发换一个思路简单的对其进行探索希望能让初学者感兴趣而不会失去学习的冲动当然这篇文章不会一下子就很完整需要一段时间的沉淀和完善我会不定时将学习到的感悟一一补充下来然后也会和别人讨论的心得写下来慢慢的将这篇文章逐渐完整起来。希望大家都积极评论混个脸熟也会挺好如果一直潜水可能都不知道你的存在。?之前的配置都是在内存中下面将如何把这些数据存储到Sql Server数据库 这样更符合生产环境的要求。好啦马上开始今天的内容~~~ 这是简单处理了下登录页要用就要好看些1、安装依赖环境 ——基础我们要把所有的数据都存储下来采用接口进行建模我们在 IdentityServer4.EntityFramework Nuget 包中提供这些接口的 EF 实现。算上我们上篇文章中引用的 IdentityServer4 包一共这三个 Nuget 依赖环境 2、三个上下文 —— 核心这一节大家如果看懂的话一定会对 IdentityServer4 丰富性和可扩展性 有特别切身的了解和体会?Z、为什么要定义多个上下文为什么要多个上下文 还记得在第二个系列 DDD 中我们说到了多个上下文的用途单个数据库可以有多个上下文。例如, 如果您的数据库包含多个数据库架构, 并且您希望将每个架构作为单独的自包含区域处理, 则此功能非常有用。在使用多个上下文类型时您还会看到其他问题 例如共享实体类型及其从一个上下文传递到另一个上下文等。一般来说设计多个上下文会使您的设计更干净, 并分离不同的功能区域但同时它的成本也增加了复杂性。框架之所以会设计成多个上下文是为了更好的扩展我们也可以部署到不同的物理机数据库中更好的实现独立性。在我们的 IdentityServer4-EF 框架中有三个上下文准确来说是 21 个上下文为什么这么说呢 因为第三个上下文不是官方定义的是我们自己根据需要进行合理扩展的比如我们可以使用 Asp.Net Core 自带的 Identity 身份认证机制来实现扩展当然你也可以自己定义相应的操作如果你还不懂就想象一下我们在 Blog.Core 项目中我们不是自己定义的基于 JWT 的认证授权么 用户表 角色表 关系表等等 但是如果你看我的 DDD 项目的话应该可以看到我又使用了 Core 官方自带的 Identity 机制毕竟结合 EFCore 我们可以很快的实现用户数据的管理而不用自己造轮子了。咱们这里先说说前两个上下文在我们使用 Ids4 的时候有两种类型的数据需要持久化到数据库中1、配置数据资源、客户端、身份//这里是对应配置上下文 ConfigurationDbContext 2、IdentityServer在使用时产生的 操作数据令牌代码和用户的授权信息consents//这里是对应操作上下文 PersistedGrantDbContext 这两个上下文以及对应的数据模型已经被 IdentityServer4 官方给封装好了 我们不需要做额外的操作直接进行迁移即可。AConfigurationDbConfigurationDbContext (IdentityServer configuration data) —— 负责数据库中对客户端、资源和 CORS 设置的配置存储如果需要从 EF 支持的数据库加载客户端、标识资源、API 资源或 CORS 数据 (而不是使用内存中配置) 则可以使用配置存储。此支持提供 IClientStore、IResura Store 和 ICorsPolicyService 扩展性点的实现。这些实现使用名为 ConfigurationDbContext 的 dbcontext 派生类对数据库中的表进行建模。更多内容请查看官网 http://docs.identityserver.io/en/latest/reference/ef.html#configuration-store-support-for-clients-resources-and-cors-settings具体在 startup 中如何配置下面会说到。BPersistedGrantDbPersistedGrantDbContext (IdentityServer operational data.) -—— 负责存储同意、授权代码、刷新令牌和引用令牌 如果需要从 EF 支持的数据库 (而不是默认的内存数据库) 加载授权授予、同意和令牌 (刷新和引用) 则可以使用操作存储。此支持提供了 IPersistedGrantStore 扩展点的实现。实现使用名为 PersistedGrantDbContext 的 dbcontext 派生类对数据库中的表进行建模。CApplicationDbApplicationDbContext 继承 IdentityDbContext (Entity Framework database context used for identity.) —— 负责与 asp. net 标识相关的用户这个上下文就是 IdentityServer4 体现 可扩展性 的关键点为什么说是可扩展的因为这是我们自己定义的你可以在这里仅仅定义一个User表也可以像我们的 Blog.Core 项目中定义三个表。我们可以在这个上下文中进行配置来控制我们的用户数据当然这里看着很简单是因为继承了 NetCore 官方的 Identity 了可以使用他们的那一套逻辑。 public class ApplicationUser : IdentityUser {//可以在这里扩展下文会说到 }// 定义用户管理上下文继承 NetCore 自带的 Identity 认证机制也可以不继承而自定义表结构。public class ApplicationDbContext : IdentityDbContextApplicationUser {public ApplicationDbContext(DbContextOptionsApplicationDbContext options) : base(options) { }protected override void OnModelCreating(ModelBuilder builder) {base.OnModelCreating(builder);// Customize the ASP.NET Identity model and override the defaults if needed.// For example, you can rename the ASP.NET Identity table names and more.// Add your customizations after calling base.OnModelCreating(builder); } }这个上下文主要是用来处理我们的用户数据相关的部分1、有多少用户数据和角色数据2、哪些用户又拥有什么角色又对应哪些Claims 声明。这一块更像是我们的平时的权限管理系统就是在 User、Role、Claim 之间交互文章下边会有一个数据模型图会很清晰的看出来各自的对应关系。我们既然需要用到这几个上下文就需要添加他们所对应的服务别着急往下看。 3、配置 EF-Ids4 相关服务 —— 必要上边我们说到了三个上下文如果我们直接执行迁移命令是会报错的比如我们直接迁移 PersistedGrantDbContext 上下文所以就需要在项目中配置对应的服务我们在 startup.cs 启动文件中配置服务 ConfigureService 配置 EF 操作数据库很简单这个就按照平时我们使用的正常的方法即可1、获取数据库连接字符串 我这里使用的是读取文件的形式其实就是字符串放到文件里了大家自己根据需要做相应调整即可我这么是防止密码泄露。2、配置数据库服务 var builder services.AddIdentityServer(options { options.Events.RaiseErrorEvents true; options.Events.RaiseInformationEvents true; options.Events.RaiseFailureEvents true; options.Events.RaiseSuccessEvents true; }) // Configures IdentityServer to use the ASP.NET Identity implementations of IUserClaimsPrincipalFactory, // IResourceOwnerPasswordValidator, and IProfileService. Also configures some of // ASP.NET Identitys options for use with IdentityServer (such as claim types to // use and authenticaiton cookie settings). .AddAspNetIdentityApplicationUser()// 添加配置数据客户端 和 资源 .AddConfigurationStore(options { options.ConfigureDbContext b b.UseSqlServer(connectionString, sql sql.MigrationsAssembly(migrationsAssembly)); })// 添加操作数据 (codes, tokens, consents) .AddOperationalStore(options { options.ConfigureDbContext b b.UseSqlServer(connectionString, sql sql.MigrationsAssembly(migrationsAssembly));// 自动清理 token 可选 options.EnableTokenCleanup true; }); 然后是我们的用户数据存储其实我们可以根据自己的需要自己建立对应的表比如我们 Blog.Core 项目中我们定义了用户、角色和关系表等数据库接口但是这样的话可能少一些情况所以一般情况下都是采用的 asp.net core 自带的 Identity 身份验证而且对扩展性很友好就比如下文我们就对用户主表做了自定义扩展继承了 IdentityUser ApplicationUser : IdentityUser // 数据库配置系统应用用户数据上下文 services.AddDbContextApplicationDbContext(options options.UseSqlServer(connectionString)); // 启用 Identity 服务 添加指定的用户和角色类型的默认标识系统配置 services.AddIdentityApplicationUser, IdentityRole() .AddEntityFrameworkStoresApplicationDbContext() .AddDefaultTokenProviders();4、Migrations 迁移 —— 结果我这里提供了两种方法至于哪种更好大家可以自己都试试我都用过可能第二种稍微多了一点不过原理都是一样的。方式一在包控制台 一、迁移项目 使用 Package Manager Console 1、add-migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb 2、add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb 3、add-migration AppDbMigration -c ApplicationDbContext -o Data 4、update-database -c PersistedGrantDbContext 5、update-database -c ConfigurationDbContext 6、update-database -c ApplicationDbContext 最后成功的生成了我们需要的数据库方式二在命令窗口判断是否支持命令行迁移你可以在项目所在的目录下打开一个命令 Power shell 并运行命令 dotnet ef 它应该是这样的 我是在 PowerShell 中操作的//1.dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb//2.dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb//3.dotnet ef migrations add AppDbMigration -c ApplicationDbContext -o Data//4.dotnet run /seed这里我就不一一操作了就是普通的命令执行生成的数据库一模一样的。但是要注意下上边我们在包管理控制台仅仅是迁移了数据库还没有进行数据 Seed 生成不过你看 PowerShell 的命令中的第四步我使用 dotnet run /seed 的命令和上边的不一样没错是因为下边我用了另一种方法通过代码的方法进行 Migrate 了并且同时还 Seed 了数据那具体如何操作呢别慌第三节我会说到了现在这个时候我们已经把数据库的所有表都已经生成好了先不着急同步数据我们先看看到底生成了哪些数据表。1、整体数据模型图我简单的做了下整个数据库的数据模型图不同模块用不同的颜色区分大家也能很清楚的看出来各自对应的关系一目了然其中配置数据又有三个部分分别对应的是 客户端 资源 身份 。 接下来咱们针对这三个模块简单的说一说因为这里还没有数据说起来可能会比较抽象这里先留一个坑等配合 Vue 客户端使用了以后再把完整数据展示出来可能更好的理解了。2、三个模块表操作数据模块 这是 Ids4 官方封装的第一部分——操作数据。PersistedGrants的数据在登陆时当你同意请求许可的时候就会在这个表里面添加一条数据。举个栗子我在 Blog.Vue 项目点击登录跳转到 BlogIdp 授权中心认证成功后跳转回来就会在这个表中多了一条数据这个功能我下次会开放出来代码已经写好MMD4TtLkVH7sXIwFS/DLZRfLQnUga0XMrBDVuQZWfOwuser_consentc2841087-1b35-4ab4-afd6-f27f80c94e6cblogvuejs2019-05-08 03:35:30.0000000NULL{SubjectId:c2841087-1b35-4ab4-afd6-f27f80c94e6c,ClientId:blogvuejs,Scopes:[openid,profile,roles,blog.core.api],CreationTime:2019-05-08T03:35:30Z,Expiration:null} 配置数据模块 这一大块是 Ids4 官方定义的第二模块 —— 配置数据从这里我们可以看出来 IdentityServer4 的另一个特性——丰富性上边咱们说到了可扩展性它提供了丰富的配置数据结构从三个方面来给我们定义好了这些数据而不用我们再去一个一个的去设计去思考。我们可以通过这些表结构来存储我们的服务数据比如有哪些API资源Blog.Core.API哪些客户端资源还有用到了哪些资源等等如果你还不清楚的可以想想上篇文章中我们讲内存模式的 Ids4 的配置就是这些数据在下边的文章中我们会进行 Seed Data那个时候我们再进一步看下。具体的数据大家可以看看截个图用户数据模块 这一块我们就很清楚了因为这是我们自定义的用户数据当然本项目是直接继承的 NetCore 的 Identity 光从数据库表名上我们就知道其中的含义了就是用户角色管理。上边咱们也简单的说了下数据库表结构然后再结合三个上下文大家应该都能明白各自的含义了好啦现在就是万事俱备只欠数据了是时候动手了还记得我们上边在生成数据库的时候我采用了两个方法第一种很常规那接下来就说说第二种中第四步 dotnet run /see 是如何操作的。1、定义 SeedData 类首先需要定义一个 SeedData 类主要是用来 update-database 和 Seed Data 这两个作用因为篇幅的原因具体的代码在 Github 上大家自行下载查看即可 2、扩展用户主表数据 上边咱们也说到了我们通过继承使用 Identity 机制来扩展了用户管理很自然的我们需要用到 IdentityUser 但是它的这个用户数据肯定不能满足我们的需求所以这里又一次体现了 Ids4 可扩展性的优点我们可以自定义用户主表 // Add profile data for application users by adding properties to the ApplicationUser classpublic class ApplicationUser : IdentityUser { // 自定义属性public string name { get; set; }public string RealName { get; set; }public int sex { get; set; } 0;public int age { get; set; }public DateTime birth { get; set; } DateTime.Now;public string addr { get; set; }public bool tdIsDelete { get; set; } }3、获取 Blog 项目用户数据 这个功能是一个充分不必要的条件主要是为了解决某些项目先用了自身一套认证系统然后又上了 IdentityServer4 项目的情况就比如我们的 Blog.Core 项目就是这个情况。那用户的数据从哪里拿到呢很巧大家还记得我在某一篇文章《 42 ║支持多种数据库 快速数据库生成》中自动生成数据库的方案就是这么使用的从 Github 上直接拉取数据即可这里整个派上用场感觉很不错private static string GitJsonFileFormat https://github.com/anjoy8/Blog.Data.Share/raw/master/Blog.Core.Data.json/{0}.tsv;// 远程获取 Blog.Core 数据库的三表数据var BlogCore_Users JsonHelper.ParseFormByJsonListsysUserInfo(GetNetData.Get(string.Format(GitJsonFileFormat, sysUserInfo)));var BlogCore_Roles JsonHelper.ParseFormByJsonListRole(GetNetData.Get(string.Format(GitJsonFileFormat, Role)));var BlogCore_UserRoles JsonHelper.ParseFormByJsonListUserRole(GetNetData.Get(string.Format(GitJsonFileFormat, UserRole)));4、执行Seed方法查看数据经历了定义上下文 - 数据库迁移 - 获取数据 - Seed Data 的过程后就剩下最后一步了执行操作很简单我在 Blog.Core 项目中采用的是 appsettings.json 文件配置的方法这里换另一种方法Program.cs 控制台参数的形式 在上一讲中我们用到了官方的 快速启动 代码里边已经包含了基本的页面当然你也可以根据自己的情况去自定义甚至采用静态的Ajax 来实现我这里还是使用的 MVC 结构只不过套用了下一个简单样式样式版权是http://www.uimaker.com/ 网站的请不要做商业用途注意产权至少看起来好看了一些。 具体的登录操作就不演示了等下次把 增删改查 都做好了再统一做下动图展示吧具体如何设计请听下回分解。 今天我们简单的实现了对 IdentityServer4-EFCore 的相关配置概念不是很难为了加深印象还是提几个小问题请大家多思考1、Ids4 一共用到了几个上下文分别的用处是什么2、在迁移中数据库生成了多少表各个模块又是干什么的3、Ids4 的良好扩展性体现在哪里丰富性又体现在哪里4、ApplicationUser 类是起到什么作用的5、思考1如果同一个用户有多个角色如何处理6、思考2如果不使用 NetCore 自带的 Identity 认证如何自定义上下文https://github.com/anjoy8/Blog.IdentityServer原文地址https://www.cnblogs.com/laozhang-is-phi/p/10660403.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com