微服务和分布式系统中的授权解决方案

本文是 《精读 Mastering ABP Framework》 2.3 探索横切关注点 - 使用授权和权限系统 一节的扩充内容,重点探讨了授权在分布式和微服务系统中遇到的挑战,以及 ABP Framework 中采用的解决方案。

认证 & 授权

  • • 认证(Authentication):确认用户身份

  • • 授权(Authorization):授予用户访问资源的权限

关于认证和授权的基础内容,可回顾:2.3 探索横切关注点 - 使用授权和权限系统 。

在微服务和分布式系统,对于权限,我们需要考虑的更多,比如:如何在一个微服务中设置权限,而在另一个微服务中检测权限,以及权限如何集中管理。

分布式系统中,认证和授权信息通常以 令牌(Token) 方式描述,所以先了解令牌内容的格式以及令牌如何存储。

访问令牌

访问令牌内容如下:

b4f7708a2bc12f4d3201fa725fbd5d4d.png
access_token_content

访问令牌内容由多个声明(Claim)组成,包含标准声明自定义声明

标准声明(claims)

  • • Sub: 用户Id

  • • Role: 用户角色

  • • Scope: 允许的范围

存储访问令牌

对于WEB应用程序,存储在浏览器本地存储(Local Storage),键为 access_tokenid_token 。

44b39041cdd59f2a1238a6027d34aa77.png
token_store

对于其他类型的应用程序,同样可以在获取到访问令牌之后,在本地存储。

授权类型 & 需求

  • • 基于声明的策略

  • • 开/关风格权限(通常是基于用户和角色)

    • • 开关数据保存在权限数据库中

  • • 自定义策略

    • • 检查权限数据库并直接应用自定义逻辑

  • • 基于资源的策略

    • • 检查权限数据库并根据请求的资源应用自定义逻辑

基于资源的策略

基于资源的策略,用一句话来描述就是:用户客户端(C)是否可以在资源(R)上执行操作(A) ?

举个例子:权限控制:当前用户是否可以编辑产品信息?

我们使用基于资源的策略,来实现以上权限控制:操作(A)对应编辑资源(R)对应产品信息用户(C)对应当前用户

关于编辑可能存在的授权逻辑:

  • • 如果产品被锁定,不允许

  • • 如果产品是由当前用户创建的,则允许

  • • 如果用户有编辑产品的权限,则允许,该权限由管理员管理用户

  • • 如果用户所属的角色有编辑权限,则允许

  • • 只有当用户在产品所属的部门中工作时,才允许

基于资源的策略,可以很好地处理以上授权逻辑。

需求:授权组件

设计一个良好的授权系统,我们通常需要考虑的四个点:

  • • 策略实施点

  • • 策略决策点

  • • 策略信息点

  • • 策略管理点

策略实施点(PEP: Policy Enforcement Point),即在哪里实施授权? 在API网关中?还是在当前服务中?

策略决策点(PDP: Policy Decision Point)即在哪里执行授权逻辑?。在当前的过程中?还是在专门的服务中?

策略信息点(PIP: Policy Information Point)即从哪里以及如何获取执行授权逻辑的数据? 直接访问数据库?还是按需收集?

策略管理点(PAP: Policy Administration Point)即直接访问数据库?按需收集? 通常系统中提供统一的管理界面。

架构讨论

基于前面授权组件的四个点,我们需要做一些讨论,以及清楚其实现方式的利弊。

讨论1:外部授权服务

策略实施点(PEP)发生在微服务中,在微服务中调用授权服务(PDP),进行权限控制。

f8730782f793ea88fde3f4b882c295bb.png
external_authorization_service

如何获取应用数据?

  • • 直接从服务数据库中读取?

  • • 在授权服务调用发送数据?

  • • 将数据预复制到授权服务的数据库中?

其他问题:

  • • 授权服务调用上的网络延迟。

  • • 授权服务成为瓶颈。

讨论2:在API网关检查

策略实施点(PEP)发生在网关中,在网关中调用授权服务(PDP),进行权限控制。

6032dbaa1fbfdf262e632fe5479e1559.png
check_api_gateway

优点

  • • 将授权逻辑与微服务解耦

  • • 防止未经授权的请求调用微服务

缺点

  • • 需要在API中自定义处理逻辑,受限于网关实现选择的技术

  • • 需要将权限映射到HTTP,如:URL, HTTP 方法和 HTTP头。

讨论3:授权类库

将策略实施点、策略决策点、策略信息点的操作封装为通用的类库,在微服务中调用管理权限。

d34178517e8a0b4b739a7fbd4dd62b49.png
authorization_library

优点

  • • 将授权逻辑与微服务逻辑解耦

  • • 应用程序数据可用

  • • 可以自定义授权逻辑

缺点

  • • 如果使用不同技术开发的微服务,如:.NET 、Python、Java,则存在问题,不能跨开发语言。

综合以上三种方案的优缺点,采用授权类库的方式

讨论4:如何保存权限数据?

方式一:每个微服务在自己的数据库中都有自己的权限表?

  • • 难以管理(加载和保存)权限

  • • 很难得到所有的权限

  • • 服务的责任太大

方式二:一个中央权限数据库?

  • • 所有服务都通过授权库直接连接到该数据库。

综合以上两种方式,采用中央权限数据库,实现策略信息点。

讨论5:如何检查和管理所有权限?

方式一:询问所有微服务的权限需求?

问题:服务发现、性能、服务上的负载太多,难以管理权限。

方式二:计算微服务中的所有权限并在中心位置预缓存?

管理和刷新缓存非常困难,任意的数据更改可能会影响许多用户的权限,缓存会太大。

方式三:在权限管理服务的中心位置计算权限?

非常适合开/关风格的权限,对微服务内部的依赖最小。

综合以上三种方式,采用在权限管理服务的中心位置计算权限,实现策略管理点(PAP)。

ABP 解决方案

基于以上的架构分析,我们来看一看在 ABP Framework 中的具体实现。

权限管理

定义权限

ac3d6b31117b77ecaf680e8eda7a80bc.png
define_permissions

检测权限

5f3650d64d3f183a68664ad1dce48fe8.png
check_permissions

授予权限

13c26ef6fd0848fe973ae219ab0ef5c3.png
grant_permissions

定义权限

c8d997ac8a5c53d225c0e1924c57ee45.png
apb_permission_define

定义权限相关参数:

  • • 权限名称

  • • 显示本地化权限名称

  • • 其他依赖:功能,全局功能

  • • 自定义数据

微服务中的权限管理

权限管理UI

e0229ff2dd0a2e464984bfc0477f7440.png
permission_manage_ui

管理UI数据来自,权限管理微服务;其他微服务中权限数据(权限定义、权限组、授权信息)保存到权限管理数据库中。

097e354d827ff972bdde6fd7af1adaa9.png
abp_permission_microservice

在权限管理微服务中和其他微服务一样使用 ABP 授权类库。

基于资源的授权

ABP 采用基于资源的授权策略

3a17a956ced42f48811b11220d03b892.png
resource_base_permission

权限过滤

需要获取 资源(实体) 列表,根据业务规则、用户预设和权限进行筛选。

dca183f7ba5ca522a5dfe992eacd88a7.png
aggregateroot_question

上图代码中,根据实体中的信息实施相应的业务规则,设置权限:

  • • OrganizationId 组织Id,允许组织

  • • CategoryId 类别Id,允许类别

  • • AssignedUserId 分配用户Id,允许分配用户可见

  • • CreatorUserId 创建用户Id,允许创建用户可见

  • • IsResolved 是否解决,在UI过滤

更新权限定义

关于服务启动

  • • 计算所有权限定义的哈希值

  • • 与分布式缓存中的哈希值进行比较

  • • 序列化和保存权限定义(仅更改/新增)

  • • 更新权限戳以通知其他服务

  • • 使用微服务名称作为缓存键前缀

2f58fa820e8f99b1c7818b4d2fae4a45.png
update_permission_define

获取权限定义

获取逻辑

  • • 如果是最新的,检查权限缓存戳并使用内存中的缓存。频率控制(30秒)。

  • • 如果不同,获取并反序列化权限定义。

在服务器启动时,预缓存权限定义。

4ae7f25b83ea8780f4da8b24707d4699.png
abp_get_permission_define

用户界面:检测所有权限

获取当前用户所有授予权限的列表!我们为什么需要它?用于控制显示或隐藏菜单项;用于控制显示或隐藏UI中的部分内容,如:按钮,标题,工具栏等;用于检查SPA的客户端权限。

968984ee626e1569ad81470c463791f3.png
check_all_permission

管理:管理所有权限

将管理一个角色或用户的所有权限在同一个地方显示。

787c16eb1df11dfb67bb2aeaa1e6d09d.png
manage_all_permission

结论

微服务和分布式系统中的授权系统设计:

  • • 设计注意事项:策略实施点、策略决策点、策略信息点和策略管理点。

  • • 集中存储权限数据。

  • • 集中管理,采用开关风格权限。

  • • 总是要求微服务自定义和基于资源的权限。

  • • 依赖数据库查询进行基于权限的过滤。

本文已收录到《精读 Mastering ABP Framework》  第六部分:扩展

a54bc6a1ecd0af1b71cea2b058bc53bc.png

精读 Mastering ABP Framework
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值