微服务下怎么做权限管理

2023-09-16 09:22:54

微服务下怎么做权限管理

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

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

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

3

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

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

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

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

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

聊技术,不止于技术。

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

更多推荐

C++学习(1)

一、C++概述(了解)C++在C语言的基础上添加了面向对象编程和泛型编程的支持二、helloword程序(掌握)#define_CET_SECURE_NO_WARNINGS//在开发软件visualstudio编译c文件时,visualstudio认为strcpy,scanf等函数不安全的导致报警告和错误,导致无法编译

CPP-Templates-2nd--第十一章 泛型库

目录11.1可调用对象(Callables)11.1.1函数对象的支持11.1.2处理成员函数以及额外的参数11.1.3函数调用的包装11.2其他一些实现泛型库的工具11.2.1类型萃取11.2.2std::addressoff()11.2.3std::declval()11.3完美转发临时变量11.4作为模板参数的引

NK试剂盒使用注意事项及NK细胞培养攻略

NK细胞自然杀伤细胞(Naturalkillercell,NK细胞),是除T细胞、B细胞之外的第三大类淋巴细胞,不表达T细胞和B细胞所特有的膜表面分子。无需抗原的预先刺激与活化即可直接杀伤被病毒感染的自身细胞或肿瘤细胞,与抗肿瘤、抗感染和免疫调节有关,是固有免疫最重要的组成成分之一。NK细胞大概约占外周血淋巴细胞的10

MongoDB性能分析

mongostatmongostat是mongdb自带的状态检测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。它的输出有以下几列:inserts/s:每秒插入次数query/s

nvm下载安装教程

前言nvm官网地址:https://nvm.uihtm.com一、nvm下载进入nvmgithub地址,下载最新版本:https://github.com/coreybutler/nvm-windows/releases点击选择当前最新版本。滑动到底部,点击nvm-setup.exe下载安装文件。接受,下一步。选择nv

中国式现代化落地社区的“3510”模式示范点在烟台正式启动

第一个中国式现代化落地社区(村居)、家庭和养老(托幼)的“3510”模式示范点——烟台市莱山区迎春佳苑智慧社区、智慧家庭、智慧养老综合服务中心于9月16日正式启动!山东省人大城环委原副主任委员尚龙江,淄博市卫健委原主任、二级巡视员宋晓东,烟台市民政局局长卢国栋,莱山区区委书记罗建,莱山区区长蒋海华,河北省山东商会副会长

使用postman做接口测试

1.接口测试:针对软件对外提供服务的接口的输入输出进行测试,以及接口间相互逻辑的测试,验证接口功能与接口描述文档的一致性2.接口测试流程:1)获取接口信息:通过接口文档或抓包来获取接口的基本调用方式和返回,抓包可以通过fiddler、charles或者chrome的开发者工具等2)接口测试用例设计:根据获取到的接口信息

PMP考试备考:两个月时间足够吗?

PMP(ProjectManagementProfessional)认证是全球范围内最受认可的项目管理专业资格之一。对于想要提升项目管理技能和职业发展的人来说,PMP认证是一个重要的里程碑。然而,很多人担心备考时间不足以充分准备PMP考试。那么,两个月的备考时间足够吗?答案并不是简单的肯定或否定。两个月的备考时间对于P

Bigemap如何添加mapbox图源?

会使用到的工具bigemapgisoffice,下载链接:BIGEMAPGISOffice-全能版打开软件,要提示需要授权和添加地图,然后去点击选择地图这个按钮,列表中有个添加按钮点进去选择添加地图的方式。第一种方式:通过地图配置文件批量解析添加地图第二种方式:通过以下在线地图的网址输入添加。mapbox:https:

爆款产品的秘诀:海外网红营销策略

近年来,随着社交媒体的兴起和全球互联网的普及,海外网红营销已成为一种极具影响力的市场推广方式。通过与知名网红合作,企业可以迅速将其产品或服务推向国际市场,实现爆款产品的目标。本文Nox聚星将和大家深入探讨海外网红营销打造爆款产品的原理,以及如何通过这一策略来创造成功的爆款产品。1、网红的选择要打造爆款产品,首先要选择合

ai智能生成文章-智能生成文章软件

您是否曾为创作内容而感到头疼不已?是否一直在寻找一种能够帮助您轻松生成高质量文章的解决方案?什么是AI智能生成文章,特别是147SEO智能原创文章生成。这是一种先进的技术,利用人工智能和自然语言处理,能够自动生成各种类型的文章。这包括了新闻报道、博客文章、产品描述、营销内容等等。这项技术的妙处在于,它可以帮助您在几分钟

热文推荐