百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

微服务权限处理,为什么这么难? 微服务的权限认证方案

bigegpt 2024-10-14 08:22 8 浏览

聊技术,不止于技术

应用拆分微服务后,一个不可避免的问题就是权限问题。拆分后的各个微服务如何处理权限,怎么处理才能保证满足业务的需求,怎么处理才能保持架构的简单及可维护?今天的文章,让我们来深入微服务架构下的权限处理问题,看看这个没有最佳实践的领域,如何能够针对业务需求来设计的较为优雅。

1

先来理解几个名词
关于权限,可能有很多相关名词,而且这些名词也很可能会让大家混淆或是疑惑(为了避免让大家产生疑惑,我就不列举这些名词了)。
但本文中会用到几个核心的有关权限的词,理解这几个词对于理解本文必不可少,所以关于权限处理至少有下述三个名词需要大家先来理解。(1)认证。(2)鉴权。(3)授权。先来说说认证。我们都会用到各种各样的系统,并且在进入系统之前都需要你输入用户名/密码,点击登录后,后台做的事就是认证,及验证你的用户名/密码是否正确,能否登录系统。这就是认证做的事。再来说说鉴权。同样的系统,不同的人登录成功后,拥有的权限是不一样的,在你进行操作时,后台会验证你是否能够进行相应的操作,这就是鉴权,及校验用户是否有相应资源的操作权限。最后来说说授权。不同的用户拥有不同的权限是通过系统授权来实现的,授权就是授予相关用户或角色资源操作的权限。当然授权可能还包含对第三方系统的授权,本文暂不讨论此类场景。其实对于大多数应用系统来说,权限处理最关键的就是要解决上述三个词所描述的问题,即系统权限处理要做的事就是认证、鉴权和授权。

2

认证、鉴权和授权,在单体应用中如何实现?
在上文中,我们说明了权限问题的核心就是解决认证、鉴权和授权问题。想要知道微服务架构中如何处理权限问题,不如让我们先看看在单体应用中是如何处理上述问题的?让我们来分别说明。(1)认证单体应用中,对于用户登录,会先校验用户的登录信息(用户名/密码),这其中可能会涉及到密码的加密处理,一般的判断是加密后相应的密码是否与数据库中存储的密码相等,如果相等的话,则登录成功。用户登录成功的话,一般会返回用户登录成功相关凭证。如果是JWT的话,则会返回Token,如果采用的是会话的话,则会通过Set-Cookie返回SessionId给客户端。(2)鉴权单体应用一般会通过拦截器(Spring Security、Apache Shrio本质上都是拦截器),拦截用户请求,这里同样会根据鉴权方案是JWT还是HTTP会话分别处理,如果是JWT的话,则会通过解密来获得用户信息,如果是采用的会话的方式,则会根据会话ID,从存储中(这里一般是Redis)来获得用户信息,不论是哪种方案,最终都是根据用户信息来对相应的请求进行权限校验。这里需要注意的是,鉴权一般有两种方式,但都是基于角色的。一种是基于角色的隐式鉴权,即根据角色直接判断是否拥有相应资源的操作权限,比如你的角色是管理员,你就可以删除用户,你的角色是普通用户,你只能查看用户信息。这种一般在简单的系统中比较适用,常用的方式是通过注解,表明哪个接口可以给哪个角色访问。但这种方式在复杂的系统中就会变得难以维护。另一种是基于角色的精准鉴权,此种鉴权方案,一般会给角色分配明确的权限,相应的鉴权方式为根据用户角色查出具体的权限集合,然后进行进一步判断。此种方式在复杂系统中更加有效方便。(3)授权在单体应用中,授权即修改用户相关角色信息,或者修改角色相关权限信息。一般在用户重新登录后,最新的权限信息生效。

3

在微服务架构下如何实现上述功能?
其实在微服务中,权限处理的认证、授权功能实现,跟单体应用没什么区别。
从微服务的基于业务拆分的原则上,对于用户相关的业务,我们都会单独创建一个用户服务,用户服务作为一个单独的微服务,在实现认证授权功能时,和单体应用保持一致即可,即相应的用户登录信息校验、用户角色修改、角色的权限修改,在用户服务中独立实现即可。所以在微服务架构下权限处理唯一与单体应用不同的便是鉴权方式。鉴权方式为什么变得不同了呢?因为鉴权不再集中在单体应用中了,鉴权被分散在了各个微服务中。所以现在问题的关键就变成了从哪里获取用户相关信息,然后在哪里进行鉴权。下面让我们来看几种微服务架构下的鉴权方案:第一种方案为,从用户服务获取用户信息,然后各个微服务分别鉴权。如下图所示:

上图中有三个微服务,分别是仓储服务、订单服务、以及用户服务,对于每个微服务的访问都需要进行鉴权,相应的鉴权方式为,所有对微服务的访问在经过网关后都统一先访问用户服务获取用户相关信息,包括角色信息、角色权限信息,然后分别在各个微服务中进行鉴权,判断用户是否有权限进行相应的操作。
上述方式的优点是实现简单,对比单体应用的实现来说,只是换了个地方获取用户信息,权限相关的判断还是保留在各个微服务中。对应的缺点也很明显,用户服务需要保证高性能、高可靠以及可扩展,并且随着服务的增多,每个服务都需要与用户服务交互,服务间调用可能会显得略加繁琐,不够简单优雅,同时每个微服务中的权限判断逻辑也都重复冗余。综上,个人并不是很推荐这种方式。其实对于第一种方案,我们略作修改,就可以得到一个略微优雅的方案,如下图,看第二种方案:

第二种方案为从用户服务获取用户信息,然后在网关进行鉴权,这样整个架构看起来是不是就清爽了许多?(美好的东西总是看起来简单的)
大家可能看到,这里将请求往具体的微服务透传的时候,带上了用户信息,这个用户信息可以放在HTTP Header中。为什么透传的时候要带上用户信息呢?因为后端具体的微服务业务可能需要获取当前用户的信息,但这里并不是用来鉴权,只是业务逻辑中用到了而已。第二种方式的优点是架构简单,对于鉴权来讲服务间调用交互更加简洁,并且后端微服务不需要冗余鉴权业务逻辑。缺点同样是用户服务需要保证高性能、高可靠以及可扩展,并且鉴权逻辑需要在网关实现。微服务的理想状态是高内聚低耦合,每个服务专注于自己的事,各个服务间功能独立,独立演进,所以针对微服务鉴权还有没有更好的方案?请看第三种方案:

鉴权要做的事是判断用户有没有相应资源的操作权限,所以从微服务的基于业务拆分的原则基础上,鉴权放在用户服务是不是更合适?所以上述方案将鉴权放在了用户服务来实现,我们不再需要调用用户服务来获取用户信息然后进行鉴权了,直接将用户的请求转发到用户服务,在用户服务中统一处理鉴权。此种方案下网关要做的事也将更加专注,只做请求的转发即可,后端各个微服务也只需专注于自己的业务即可。
此种方案,在我看来是比较推荐的方案,并且应该能满足微服务架构下大多数系统的权限处理需求。当然缺点是对用户服务的高性能、高可靠以及可扩展提出了更高的要求。除了上述三种鉴权方式,微服务架构下可能还有其他鉴权方式,比如共享用户信息缓存的方式,这种方式下,各个微服务统一从缓存获取用户信息,然后分别在各自进行鉴权。基于此种方式也很容易想到一个优化的变种,即从网关获取缓存的用户信息,然后在网关进行鉴权。诸如此类的鉴权方式,我个人是不太推荐的,当然采用此类鉴权方式的团队可能也有他们的考虑,更多的可能是出于性能的考虑。至于我为什么不推荐诸如此类的方式呢,我觉得我们在做系统架构的时候需要有自己的原则,其实对于很多问题我们可以有许多种解决方法,哪种方案比哪种好可能并不好说,甚至团队在方案的选择上还会有所争执,但如果在架构设计上团队有自己的指导原则的话,可能能够帮助我们在方案的选择上达成共识。个人在架构设计上的原则包括但不限于可维护原则、可扩展原则、简单性原则等,所以与其说此类方案不好,倒不如说这并不符合我的设计原则。

写在最后
应用拆分微服务后,一个不可避免的问题是权限问题。
权限问题要解决的核心问题是认证、鉴权和授权。在说明微服务架构下如何处理权限问题之前,我们先看了单体应用下是如何处理权限问题的认证、鉴权和授权的。对于微服务来讲,权限问题的处理与单体应用中的处理最大的不同是鉴权的方式,至于认证、授权的实现与单体应用并无太大不同,在微服务中的用户服务下实现即可。微服务下鉴权处理为什么变得不同了呢?因为鉴权不再集中在单体应用中了,鉴权被分散在了各个微服务中。所以问题的关键是微服务下该从哪里获取用户相关信息,然后在哪里进行鉴权。我们详细介绍了微服务架构下三种鉴权的实现,第一种方式是从用户服务获取用户信息,然后在各个微服务中鉴权。第二种方式是从用户服务获取用户信息,然后在网关统一鉴权。第三种方式不再需要获取用户信息,直接通过网关转发请求,在用户服务进行统一鉴权,各个服务的职责划分更加明确,也是个人推荐的实现方式。除此之外,还介绍了一些其他的鉴权实现方案,问题的解决方案并不唯一,有时候也很难说出哪种更好,我们要有自己的设计原则。


聊技术,不止于技术。

在这里我会分享技术文章、管理知识以及个人的思想感悟,欢迎点击关注。

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...