从壹开始 [ Ids4实战 ] 之五 ║ 多项目集成统一认证中心的思考

前言

哈喽你们好,很久都没有写文章了,此次又从新开始写技术文章了,半年前我仍是一直保持每周都写文章的,后来是为了响应群友的号召,开始踏上了录制视频(https://www.bilibili.com/video/av58096866),直播授课https://live.bilibili.com/21507364的道路,目前看来效果还算基本及格吧,虽然人气没有那些大佬的多,不过我也是一直很尽心力,包括字幕的录入,每周三按期的讲课,不过真的很累,可是自认为作的还能够了,只是没能申请上MVP,今年惟一的遗憾🙃。html

 

编者按:git

不少小伙伴说,学不懂受权认证,搞不懂 IdentityServer4 ,看不懂文章啥意思。固然具体怎么采用仍是看所在公司的技术能力上限,可是从我的将来知识规划出发,这些知识点仍是须要考虑的,有益无害。github

 

为何忽然想要写文章了呢,我是有强迫症的,目前开源了五个系列的文章,从 NetCore 到 Vue,从 Admin 到 Nuxt,而后从 DDD 到 IdentityServer4,我自认为都是贴近实战的,由于看到某些小伙伴说,应用到了公司的项目里,我也是很开心,并且 NetCore 项目的Github start 数也破千了,我感谢每个点赞评论的小伙伴,我都是每条评论必回,每一个邮件也必回:数据库

我自信这一年多以来,对netcore的基础知识已经了解的七七八八了,基本都能回答些,可是每当有人问到 IdentityServer4 的相关内容的时候,我都稍微捉襟见肘,虽然我写了四篇文章,可是由于中间卡了一个心结(具体内容下文会说明),因此没有进行下去,也让本身没有进一步去研究这个框架的动力了,你们确定都懂那个心理,若是一直有个刺,而后时间长了会刻意回避它。后端

 

不过最后我仍是决定要搞起来,既然说到了要布道,就要走下去,因此我会除了以前的四篇文章外,还再有三到四篇的文章来开启 Ids4 的第二阶段的学习,而后配合还有大概八个视频的讲解,若是你看过个人第一个系列视频教程,应该内心有谱,我第二个系列讲的怎么样,因此我也就很少说了,这两周准备一下,下周末开启视频讲解第二系列。api

那下面咱们就立刻开启今天的这篇文章吧。服务器

 

 

零、回顾与目标

 还记得我开启 IdentityServer4 讲解是在半年前,当时我本想是八篇文章,将个人全部项目 —— 主要是 Blog.Admin 和 Blog.Vue 这两个项目统一集成到 Ids4 的网关受权上来,固然有精力也能够把 DDD 和 Nuxt 的认证也添加进来,只不过 DDD 已经用了 Identity 了,这个优先级能够暂时日后放放,而后就写了四篇文章,主要是偏重于实战,而不是讲解那老生常谈的知识点:框架

 

 

可是在写到了第四篇文章的时候,出现了一个说小不小,说大不大的问题,让我搁置了整整半年,是什么问题,我简单说说:dom

我看博客园不少博主在讲 Ids4 的时候,基本状况都是用的无状态的认证方式,什么意思呢?分布式

一、就是应用场景都是对应的 [Authorize] 这种只要登陆了就能够的项目里,没有涉及到复杂的策略受权,好比角色和模块;

二、而后你可能也会说,“ 我看到他们文章讲解中生成的 token 中,能够自定义 Role 到 Claim 里呀,你直接在 Blog.Core 项目获取到 Role 进行策略受权不就好了”,你说的没错,可是这里有一个后续问题;

三、那个人 Role 信息在哪里管理?是在 Blog.Ids4 (认证服务)项目,仍是在 Blog.Core (业务资源服务)项目里?

这里你能够稍微暂停一下,暂停五分钟,本身想想,如何去解决这些问题,特别是第三个问题。

若是你把 Role 的信息管理放到了 Blog.Ids4 项目里,那 Blog.Core 如何针对 Role 进行匹配 Url进行受权配置呢?

可是若是把 Role 管理放到了 Blog.Core 项目里,那就没有办法根据 UName 和 Pwd 生成 token 的时候,在 Claims 里生成 Role 信息了。

 

这个并无那么简单哟,固然若是大家公司开发过,能够直接看下文,和我想的方案对比下,若是有出入,或者你的更好,我热烈欢迎提出批评和指导建议,好了,那我就说说个人三种思路吧。

 

1、无状态的简单受权认证

 

这种方案呢,刚刚咱们在上文已经说到了,我也已经实现了,就是在文末个人项目中,已经实现这个了, 就是 Blog.Ids4 只单单提供认证功能,不用管 Role 的相关声明 Claims,基本都是对应的前台项目,好比咱们的博客项目和电商项目,用户登陆了就行,就能够直接发文章或者购买商品了,不用理睬具体啥页面不能访问,这个就很少说了,很好理解。

这种场景,很好解决,认证服务项目和资源服务项目 相互独立,没有交际,只是提供一个认证网关的做用,这里就很少说了。

 

可是这种状况有时候并非不少,或者说是少数的,咱们更多的,仍是须要在 token  中携带 role 的 claim 声明,特别是后台管理系统,都是有状态的受权,好比咱们的 Blog.Core 是比较复杂的策略受权,那这个时候就须要讨论一下数据库的问题了,其实重点仍是讨论 Role 表是在哪一个项目维护的问题。

 

 

2、有状态的受权认证中心

 

那么问题就来了,咱们为了知足复杂的策略受权,就须要在 Blog.Core 项目里将 Role 和 Url/Api 进行匹配映射到数据库,那就必须用 Role 表。

可是咱们上边也讨论不少了,咱们必需要在 token 中携带 Role 的Claim,那就必须放到 Blog.Ids4 项目里维护 Role。

这个时候是否是发现两种状况很矛盾,为了达到这个项目,我简单看了看 ABP 项目,这个仍是群管理 @Kawhi 提的建议,我获得了一丝丝的想法,ABP项目是把认证和资源服务合并到了一块儿!

 

一、认证数据库与业务数据库合二为一

 

这个我最终决定采用的方案这个方案已经放弃,我如今Blog.Core资源服务器已经支持多库了,能够不用合并了,

具体代码我已经慢慢的在 Ids4 项目里迁移修改了,感兴趣的能够看看,其实说白了,就是把 EFCore 生成表结构的数据库,指向 Blog.Core 项目的就好了,而后这个时候,咱们就看到了两个 Role 表:

 

那既然咱们的 Ids4 项目用的是 AspNetRoles 来进行认证的,咱们直接用这个表不就行了?!,舍弃下边的 Role 表,用上边 Ids4 自带的 AspNetRoles 表,来和咱们的 Module 和 Permission 表就行受权映射匹配,这样是否是完美的解决了咱们上边出现的全部问题!

 

而后咱们的 User 管理和 Role 管理,都移交到了 Ids4 项目里,从而使得咱们的 Blog.Coe 资源服务器只须要踏踏实实的作受权就好了:

 

 

这个不用担忧看不懂,我在后边的文章和视频中也会详细说到,本文主要说的是这个思路,具体业务逻辑和代码,我会详细讲解的,你能看懂个人意思就行。 

这样是否是很好的解决了 Role 管理的问题,并且能够快速的将 Blog.Admin 和 Vue 项目给切换过来,很简单。可是,万事就怕可是😂,这里有一个问题,就是若是我有多个资源服务器怎么办,多个资源服务器确定是不能和一个认证数据库合并的,好比个人项目结构是这样的:

 

 

 

 

这种咱们是很差去把 资源服务器和 认证中心的数据库放到一块儿的,固然这种微服务的方案也不是这么玩儿的,我之后会继续说到这种状况,如何来设计。

我们先不说微服务,就说单一服务,那若是不能数据库合并,又想保证 Role 的良好维护,我想了不是很好的办法,一共分下边几种状况。

 

二、认证DB与资源DB分离,两个Role表

既然不放到一块儿,那就分离开,仍是我目前项目 Github 上的状况,两个数据库,两个 Role 表 ,可是呢,对 Role 的管理,仍是放到 Ids4 服务器,

只不过这个时候,须要在资源服务器 Blog.Core 里,写一个定时器或者服务,将 Ids4 Db 中的 AspNetRoles 表数据,统一导入到 Blog.Core Db 的 Roles 表中,而后咱们在资源服务器仍是来操做 Roles 表,基本个人资源服务器修改的代码不多,只是多了一个数据同步的方法而已,

 

 

 

相对于上边的方案,这个优势是:

一、代码改动小;

二、多个资源服务器能够共存,共用一个认证中心;

三、防止由于 IdentityServer4 官方更新,而破坏咱们的资源服务代码,侵入性小。

 

缺点也是有的,就是比较 low,并且不能保证明时性,更新速度受到定时器的限制。那和老李讨论一下,他给的建议是,能够在不使用表同步,而使用接口的形式,请往下看。

 

三、认证DB与资源DB分离,一个Role表,经过接口调用

这种方案,最终被我 PASS 了,思路我简单说下,其实很简单,就是咱们的资源服务器 Role 表弃用,整个项目统一用 Ids4 认证服务器提供一个对外暴露的 GetRoles 的 api 接口,来保证明时性和统一性,

可是这样缺点太明显,受官网的限制,并且对资源服务器的侵入性太强,尽管能够封装一个方法。

 

 

 

说这个的目的,只是想让你们集思广益,开拓思惟,学习都是思考的过程。

 

四、【推荐】认证DB和资源DB分离,一个Role表,多库操做

这个方案是有条件的,资源服务器必须是支持多库操做的,目前个人Blog.Core项目已经支持了多库操做,配置一下,就能够获取 Blog.Idp 项目中的 Role 信息了,是很方便的。

可是若是你的资源服务器不支持多库操做,那我仍是建议使用第一种方案(数据库合并),和第三种吧(经过 idp 项目提供一个role的接口)。

 

 

 

 

 

五、分离 Role 分布式服务管理中心

这个是一个不肯透露姓名的群友的建议,我原本想放到其余方案里,可是感受也是很不错的,这里单放出来,我我的也没有考虑到他的这一点 —— 抽离出 Role 管理中心,作分布式服务给 认证中心

具体来讲是什么意思呢,我这里继续画一个图就知道了:

 

 

 这样不只能够解决 Role 同步问题,还能很好的进行扩展,咱们不管增长多少个 资源服务器,只须要向 Role 管理中心,推送相应的Role就行,而后咱们的 Ids4 认证中心,只须要从 Role 管理中心获取,你能够经过资源服务器的 domain 来作区分,来管理 User。

 

 

3、其余方案

具体的请看下边的评论哟,评论也很精彩!!!

 除了我上边提出来的一些方案,若是你有什么想法,或者好的注意,能够文章下边留言或者评论,不胜感激,好比:

一、@老张说:不在资源服务器里进行数据库的映射匹配,所有写到Controller控制器的特性上的角色或模块受权[Authorize(Roles = "Admin,Client")],这样也能解决。

二、@你们说:这里我就不写名字了,评论区的小伙伴较多的仍是采用【拆分服务,合并数据库】的模式,这样代码也不会乱,数据也很好同步效果。

 

期待你的热评! 

 

 

4、Github && Gitee

 https://github.com/anjoy8/Blog.IdentityServer

原文出处:https://www.cnblogs.com/laozhang-is-phi/p/11844395.html

相关文章
相关标签/搜索