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

前言

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

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

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

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

那下面我们就马上开启今天的这篇文章吧。

零、回顾与目标

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

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

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

1、就是应用场景都是对应的 [Authorize] 这种只要登录了就可以的项目里,没有涉及到复杂的策略授权,比如角色和模块;

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

3、那我的 Role 信息在哪里管理?是在 Blog.Ids4 (认证服务)项目,还是在 Blog.Core (业务资源服务)项目里?

这里你可以稍微暂停一下,暂停五分钟,自己想一想,如何去解决这些问题,特别是第三个问题。

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

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

这个并没有那么简单哟,当然如果你们公司开发过,可以直接看下文,和我想的方案对比下,如果有出入,或者你的更好,我热烈欢迎提出批评和指导建议,好了,那我就说说我的三种思路吧。

一、无状态的简单授权认证

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

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

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

二、有状态的授权认证中心

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

但是我们上边也讨论很多了,我们必须要在 token 中携带 Role 的Claim,那就必须放到 Blog.Ids4 项目里维护 Role。

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

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

这个我最终决定采用的方案,具体代码我已经慢慢的在 Ids4 项目里迁移修改了,感兴趣的可以看看,其实说白了,就是把 EFCore 生成表结构的数据库,指向 Blog.Core 项目的就行了,然后这个时候,我们就看到了两个 Role 表:

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

然后我们的 User 管理和 Role 管理,都移交到了 Ids4 项目里,从而使得我们的 Blog.Coe 资源服务器只需要踏踏实实的做授权就行了:

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

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

这种我们是不好去把 资源服务器和 认证中心的数据库放到一起的,当然这种微服务的方案也不是这么玩儿的,我以后会继续说到这种情况,如何来设计。

咱们先不说微服务,就说单一服务,那如果不能数据库合并,又想保证 Role 的良好维护,我想了不是很好的办法,一共分两种情况。

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

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

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

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

1、代码改动小;

2、多个资源服务器可以共存,共用一个认证中心;

3、防止因为 IdentityServer4 官方更新,而破坏我们的资源服务代码,侵入性小。

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

3、认证DB与资源DB分离,一个Role表

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

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

说这个的目的,只是想让大家集思广益,开拓思维,学习都是思考的过程。

三、其他方案

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

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

2、???

期待你的热评! 

四、Github && Gitee

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

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

时间: 2024-10-18 17:29:57

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

【实战】某项目SQL注入引发的思考

数据包: 测试参数:username,测试payload: ' ' or '1'='1 ' or '1'='2 响应结果都未发生任何变化,借助sqlmap测试,结果一样: 尝试在or前面进行简单的fuzz,结果为: 发现' or 1=1 or '1'='1可以直接登录系统,也就是说此处是存在sql注入的,构造payload,借助sqlmap检测 进一步分析,or 1=1 为true,说明后边or '1'='1语句在数据库中执行结果为false,猜测也许在or '1'='1后边还有其它未知的字符,

[Java聊天室服务器]实战之五 读写循环(服务端)

前言 学习任何一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列虽然涉及的是socket相关的知识,但学习之前,更想和广大程序员分享的是一种心境:学习是一个循序渐进的过程,心态应该随时调节,保持戒骄戒躁的状态.比如最近在看网易公开课MIT<算法导论>,老师提到,学习算法之前要计算机数学+离散数学+概率论等课程的知识,所以一直学不好算法的程序员不妨从基础入手,这都是中国式教育惹的祸啊!(此处省略一万字......)

下载深入浅出Hadoop Mahout数据挖掘实战(算法分析、项目实战、中文分词技术)

随着云计算.大数据迅速发展,亟需用hadoop解决大数据量高并发访问的瓶颈.谷歌.淘宝.百度.京东等底层都应用hadoop.越来越多的企 业急需引入hadoop技术人才.由于掌握Hadoop技术的开发人员并不多,直接导致了这几年hadoop技术的薪水远高于JavaEE及 Android程序员.Hadoop入门薪资已经达到了 8K 以上,工作1年可达到 1.2W 以上,具有2-3年工作经验的hadoop人才年薪可以达到 30万—50万 . 深入浅出Hadoop Mahout数据挖掘实战(算法分析.

【思库教育】2017PHP项目实战基础+进阶+项目之基础篇

下载链接: [思库教育]2017PHP项目实战基础+进阶+项目之基础篇 小白变大牛,您的专属资源库! 小白变大牛,您的专属资源库! 内容非常充实,可以看目录,设计的面多,项目多,技能多,如果掌握好,找一份PHP的工作,易如反掌!学完后可以到PHP小白变大牛精华区查找更加符合你的资源或者项目! [思库教育]2017PHP项目实战基础+进阶+项目之基础篇[思库教育]2017PHP项目实战基础+进阶+项目之进阶篇[思库教育]2017PHP项目实战基础+进阶+项目之项目篇小白变大牛!Python小白,J

手把手教导实战Python Web项目

手把手教导实战Python Web项目 一.前言 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的框架模式,即模型M,视图V和控制器C.Django的主要目的是简便.快速的开发数据库驱动的网站.它强调代码复用,多个组件可以很方便的以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包.这使得Django具有很强的可扩展性. 二.开发环境 Python3.7.4 Django2.0 Django安装 安装

K8S实战-构建Django项目-06-持续构建

今天是K8S实战-构建Django项目,最后一讲.前面5将我们一步步通过k8s构建了一个django项目,通过考虑实际生产环境,我们添加了初始化功能,自动化构建功能,共享存储,数据加密,监控方案,日志方案.从无到有,我们一同走了一遍.最后一讲,我将带着大家利用现有的资源实现最简单的持续构建. 持续构建 设计 gitlab+jenkins+node+dockerfile+k8s gitlab作为仓库,jenkins设置触发器,node作为执行节点,dockerfile生产镜像,k8s构建资源. 实

K8S实战-构建Django项目-03-使用共享存储

上篇博文,发布之后,正好跟着双十一,不知道大家剁手了没~~.好啦,言归正传先声明一下,每周1,3,5更新教程,大家如果想要了解更多的教程可以重温一下之前的教程或者,关注崔格拉斯 公众号,大家想要源码的可以私信我~ 每日解析(11.9 每日一题解析) 昨天的教程中留下了一个问题:如何实现数据持久化,确保django project和数据库文件不随pod的销毁而销毁. 解析: 在上一篇教程中,我们已经使用了emptyDir 数据卷.这种数据卷对于当个容器来说是持久的,但是对于Pod来说并不是持久的.

Spring学习(一)tomcat加载web.xml、以及项目集成Spring支持

tomcat容器加载web.xml 一. 1 .启动一个 WEB 项目的时候, WEB 容器会去读取它的配置文件 web.xml ,读取 <listener> 和 <context-param> 两个结点. 2 .紧急着,容创建一个 ServletContext ( servlet 上下文),这个 web 项目的所有部分都将共享这个上下文. 3 .容器将 <context-param> 转换为键值对,并交给 servletContext . 4 .容器创建 <li

SpringMVC将一个项目集成在另一个项目中

将KissfloveUtil项目集成在自己项目中.在pom.xml中加入以下配置: <dependencies> <dependency> <groupId>com.kissflove</groupId> <artifactId>kissfloveUtil</artifactId> <version>0.0.1</version> </dependency> </dependencies>