记ABAC的落地实践
为什么使用ABAC
一般提到授权,我们就会想到角色(role)。什么样的用户拥有什么样的角色可以怎么操作什么样的资源,这是我们普遍使用的权限系统的模型。这里的角色实质上是包含了一组用户操作资源的规则集合。一旦角色被创建,也就意味着有一组资源操作集合被固化起来,除非去修改角色,否则这个规则集合是不会变的。 比如在一个图书馆的图书管理系统中,所有读者都可以查看书籍及其不同的分类,图书管理员编辑图书信息,管理层可能要看一些图书借阅报表等。这些都可以给读者和图书管理员分配不同的角色就可以实现。在一个较大的图书馆,图书管理员可能分布在不同楼层或者管理不同类别的图书,所以我们需要创建多个图书管理员的角色,比如: 二楼图书管理员,或经济类图书管理员等。更大的图书馆可能会有出版社区分的管理员或者代理人员,因此会有更多基于出版社和图书分类的角色。随着该图书馆的不断扩大,业务职责越来越精细,会继续不断的创建新的角色,比如对于一个出版社在一个楼层的一个特定分类的按照出版时间进行不同角色管理,就会有 “出版社数 x 楼层数 x 楼层图书分类数 x 出版时间分类数” 的角色创建,如此下去,整个系统就会面临“角色爆炸”的窘态。
上述描述的就是基于角色的访问控制,简称RBAC(Role-Based Access Control)它他是一种静态的访问控制模型,主要用于一些基本的简单授权系统中。那如果我们需要更细粒度的访问控制,而又不想面临“角色爆炸”,基于属性的访问控制,简称ABAC(Attribute-Based Access Control)可以是一种选择。在ABAC的模型中没有角色的概念,也就没有“角色爆炸”,它是通过定义一系列的访问规则,利用当前用户操作相关资源的属性,动态的决定用户有没有权限操作该资源。当前著名的AWS IAM就是使用ABAC管理访问控制的,也称PBAC(Policy-Based Access Control)。
ABAC模型和框架
在ABAC的概念模型中,主要包含:
- 访问者(Subject):指操作的发起者,可能是一个用户,或一个系统。
- 受访者(Object):指操作的接受者,也就是访问目标资源,例如用户数据等。
- 操作(Operation):即对受访者的操作,常见的增删改查等。
- 属性(Attribute):指一组来自访问者,受访者,和操作相关的数据,也包含一些环境上下文数据。
- 策略(Policy):指可以基于属性动态生成访问控制结果的预定义的一组规则。
但ABAC毕竟只是个模型,要真正实现它,最好依赖于一种成熟的框架。XACML(eXtensible Access Control Markup Language 可扩展的访问控制标记语言)是一个标准的ABAC框架,它详细的定义了ABAC中的每一个概念和实现方式。它定义的ABAC系统主要包含4个组件:
- 策略执行点(PEP):最终执行策略结果的地方,决定要不要继续访问资源。
- 策略决策点(PDP):通过策略和属性信息决定有无权限进行操作的地方。
- 策略信息点(PIP):为执行决策提供额外属性的地方,可以是一个或者多个额外系统。
- 策略管理点(PAP):管理和配置策略的地方。
其直接关系如下图:
ABAC的实现
有了XACML的框架支持,对于ABAC的实现,我们可以按需裁减。首先我们看下系统的结构图,这样更明确下我们ABAC系统的地位和职责。
我们可以把MyABAC 看作访问者与被访者之间的一个层,类似于apiGateway 或BFF,也可以看作是受访者的代理,类似于nginx等。暂且不管它是什么,他的职责就是拦截或者转发请求。明确了这一点之后, 我们用前后端的例子将其具象化:(这里的frontend 可以是一个UI,或一个服务等)
有了具象的实例,随后就可以按照XACML的框架,迭代式的完成相对应的组件。
迭代一: PEP
核心的功能在于PEP拦截和转发来自前端的请求。所以这个版本的MyABAC有两个基本功能,1: 判断请求权限,2: 转发或拒绝请求。对于拒绝请求,可以直接返回401, 对于转发请求,我们可以创建一个ProxyServer 完整的转发整个请求。但是对于判断请求权限,要怎么处理,根据什么判断呢?ABAC中的属性就是我们判断的数据源,目前我们能拿到的数据仅仅来自于请求本身或者当前环境的上下文(Context),所以我们用一段静态逻辑从请求本身获取一些属性,用一个简单的判断进行验证。为了能适应在不同的请求当中,可以这段获取请求属性的逻辑抽象成为一个组件,权且叫它为extractor
. 那么我们就有了第一个版本:
迭代二: PEP + PDP
在上一个版本中我们已经实现了MyABAC 对请求的转发,和简单的基本判断。接下来可以逐渐丰富请求的判断。按照XACML的机构,PEP仅仅负责对鉴权结果的执行,对于鉴权真正的逻辑应该在PDP中执行。所以PDP中一个很重要的组件就是决策器(Decision Maker),我们选择’Permit’和’Deny’ 代表决策的结果。这样就可以在PEP 中设置一个PDP client, 将Extractor拿到的属性传递给PDP, 然后将PDP的结果给Validation来判断是否转发请求。PDP 拿到 PEP 传递的属性值之后不再是简单的判断,它将通过一系列的规则(Rule) ,每个规则都有自己的匹配条件(Condition)和结果(Effect), 不同的规则按一定的关系进行分组,每一组我们称之为一个策略(Policy). 每一个策略里按照一定的算法(R****ule-combining Algorithm)将规则结果归结为一个结果(Effect). 至此,PDP将有两个基本部分,决策器也按照策略的组合算法(Policy-combining algorithm)将结果归结, 返回给 PEP。如下图:
在具体的实现中,PDP和PEP可以是一个系统中的不同组件直接调用,也可以部署为不同的服务,使用HTTP请求。在MyABAC为了更好的微服务化,我们将PEP和PDP部署为两个系统,使用HTTP请求。
迭代三: PEP + PDP + PAP
上个迭代中,MyABAC 有了PDP 和 策略,但是对于策略还仅仅局限在一堆代码逻辑中,如何更好的管理这些策略,如何让策略和人(即系统的管理员或运维人员)合理的管理和交互,这便是PAP的主要职责。策略和规则中有一定的的逻辑组合关系来组成相对应满足的条件,对于它的定义,XACML 有一套比较复杂的基于XML的逻辑语言,但这里我们将其简化,借鉴AWS cloudformation 的语言结构,构建了一个自己的基于YAML的配置语言,姑且称之为 MPL(MyAbac Policy Language)。将每一个策略简化成为可读性较好的yaml文件,那么PAP的职责就是使用UI或者编辑器(Editor) 对yaml文件的维护。而PDP中将会有一个编译器(MPL Compiler) 将PAP 完成的策略文件,编译成为PDP可以使用的策略。这样在以后的操作过程中,仅仅通过 PAP 就可以对策略进行改变。
有了MPL的帮助,策略文件看起来也就清晰简单了。 下图前边是XACML的策略文件, 后边是MyABAC的策略文件。
迭代四: PEP + PDP + PAP + PIP
有了PDP做鉴权,PEP执行结果,PAP管理策略,看起来似乎已经完成了,但是当真正投产的时候,就会发现仅仅依靠从请求中拿到的少量属性来做真正的鉴权是远远不够的,就拿上面图书管理系统来说,怎么知道一个管理员具体的职责在几楼哪个类别,怎么知道图书的信息?一般的请求当中仅仅只有一个图书的编号和管理员的编号,更多信息就需要到对应系统中请求,而这些能够提供更过信息来支持PDP做出合理判断的服务或者产品,我们称之为PIP。也就说 PIP 并不是 MyABAC 的内在组件,而是一个外部的第三方组件。这些服务可能是基于http Restful的接口,也可能是一个GraphQL的接口或者其他类型的接口。但是为了能够让 PDP 与这些PIP正确的调用,PIP 必须遵循 PDP 制定的协议,这样 PDP 才能合理传递个 PIP 必要的信息,从而获取想要的信息,比如通过管理员的编号或者管理员服务的楼层号码和服务的图书类型编号。这一切都封装在PDP 中的 PIP Client组件里。这样决策器(Decision Maker) 不仅拥有从PEP中extractor中的属性,而且可以通过PIP拿到更多想要的属性值,同时每个属性值的变化会及时反馈到PDP中,动态的参与了最终结果决断。从而达到了更细粒度的访问控制。同样我们也可以将PAP从MyABAC里分离出来,管理多个系统的策略。比如我们可能部署多个MyABAC来保护不同的服务,这样系统中的策略是不一样,但是可以使用同一个中心化PAP来管理多个系统的策略文件。
迭代五: 未来的计划
通过上面的迭代,一个比较完整的ABAC的MVP已经完成。由于在原始的请求中添加了额外的工作量,比如额外的请求,包括PEP到PDP的请求、PDP到PIP的请求等,要核对很多的策略,所以性能问题是MyABAC不能忽视的问题。再次迭代中将使用懒加载,缓存的机制来优化MyABAC的性能。同时此产品对XCAML的框架做了大量的裁决,只采纳一些基本概念和组件,所以要关注用户的使用和需求反馈,逐步的引入更多概念来不断的完善产品。
后记
相对于RBAC,ABAC的概念更广,实现更复杂。如果把角色(role)当作唯一的属性,那么RBAC就是一个ABAC的特列。对ABAC和RBAC的选择要基于当前业务的需求。不要将简单的问题复杂化,也不能把复杂的问题看的太过简单。MyABAC的出现,将系统中的鉴权部分完全从系统中抽离出来,让系统的设计者和开发者更加关注在具体的业务实现上。作为一个完全自管理的产品,可以以边车(sidecar)的形式部署在每个系统中,甚至可以部署在一套系统中不同层级(layer),比如BFF层,API层或数据库层。 但同时也增加了系统部署的复杂性,我们要合理的选择和取舍。
目前,MyABAC已经在公司多个系统中使用,根据用户的反馈已经引入了一些新的功能,比如对义务(Obligation)的支持等。在部署中我们将MyABAC封装称为一个docker image,这样用户就不会过多的关注它的具体实现,而仅仅通过一些简单的参数配置就可以完成对MyABAC的引入。
参考:
https://en.wikipedia.org/wiki/Attribute-based_access_control
http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html
相关文章:

记ABAC的落地实践
为什么使用ABAC 一般提到授权,我们就会想到角色(role)。什么样的用户拥有什么样的角色可以怎么操作什么样的资源,这是我们普遍使用的权限系统的模型。这里的角色实质上是包含了一组用户操作资源的规则集合。一旦角色被创建&#…...

【C++】C++11线程库 和 C++IO流
春风若有怜花意,可否许我再少年。 文章目录 一、C11线程库1.thread类介绍2.mutex互斥锁 和 CAS原子操作(compare and set)3.lock_guard和unique_lock4.两个线程交替打印,一个打印奇数,一个打印偶数(线程同步…...

cpp11实现线程池(六)——线程池任务返回值类型Result实现
介绍 提交任务函数submitTask中返回的Result类型应该是用Result类包装当前的task,因为出函数之后task即如下形式:return Result(task); Result和Task都要互相持有对方的指针,Task要将任务执行结果通过Result::setVal(run()) 调用传给其对应…...

道岔外锁闭装置介绍
简述 道岔外锁闭装置是一种能可靠地锁闭尖轨和基本轨的器械。它能有效地克服尖轨在密贴时的转换阻力,即使连接杆折断,外锁闭装置仍在起着锁闭作用。外锁闭能够隔离列车通过时对转换设备的振动和冲击,提高转换设备寿命和可靠性。 产品分类 …...

idea把项目上传到码云
1. 为项目创建仓库 2. 选中中项目右击git, 先add, 在commit Directory 3. 设置远程码云项目地址 4. push项目, ok。 注意: 如果你在最后push出现以下提示,则说明提交失败 Push to origin/master was rejected(译文:推送到原点/master被拒绝…...
设计模式之责任链模式
责任链模式的定义是:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。 责任链模式适合于请求需要经过多个处理器,并…...
Python--我一般都用这个模块压缩文件
打包成压缩文件很多时候都能用上,也包括了自动化中的部分应用。例如,将测试报告打包发送。 本章就来介绍其中一个模块,可以用于结合上一章的内容结合使用。 from zipfile import ZipFile ❝ ZipFile是zipfile的一个方法。 ❞ 提取zip文件 fro…...

Chapter8 :Physical Constraints(ug903)
8.1About Physical Constraints(关于物理约束) XilinxVivado集成设计环境(IDE)允许通过设置对象属性值对设计对象进行物理约束。示例包括: •I/O约束,如位置和I/O标准 •布局约束&…...

星标3.5k,一款国产的轻量级开源在线项目任务管理工具
今天给大家推荐一个轻量级的开源在线项目任务管理工具:DooTask 图片 DooTask 提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM,文件管理等工具。 高效便捷的团队沟通工具 针对项目和任务建立群组,工作问题可…...
【华为OD机试真题2023B卷 JAVA】字符串摘要
华为OD2023(B卷)机试题库全覆盖,刷题指南点这里 字符串摘要 知识点字符串排序 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 给定一个字符串的摘要算法,请输出给定字符串的摘要值。 1、去除字符串中非字母的符号。 2、如果出现连续字符(不区分大小写),则输…...

Java线程概述 (一)线程介绍
文章目录 🐒个人主页🏅JavaSE系列专栏📖前言:🪅什么是程序 、进程、线程?🪅线程的生命周期🪅多线程🪅守护者线程🪅线程并行与并发🪅死锁…...

操作系统第三章——存储系统(下)
锦衣雪华玉颜色,回眸一笑天下倾 文章目录 3.2.1 虚拟内存的基本概念知识总览传统存储方式的特征,缺点局部性原理虚拟内存的定义如何实现虚拟内存技术知识总结 3.2.2 请求分页管理方式知识总览页表机制缺页中断机制地址变换机制知识回顾 3.2.3 页面置换算…...

初识结构体
目录 结构体的声明 结构体的基础知识 结构体的声明 结构体成员的类型 结构体变量的定义和初始化 定义 初始化 结构体成员的访问 结构体变量访问成员 结构体指针访问指向变量的成员 结构体传参 传地址 传结构体 结论 结构体的声明 结构体的基础知识 数组ÿ…...
协程并发下数据汇总:除了互斥锁,还有其他方式吗?
1. 简介 本文介绍了在并发编程中数据汇总的问题,并探讨了在并发环境下使用互斥锁和通道两种方式来保证数据安全性的方法。 首先,通过一个实例,描述了一个并发拉取数据并汇总的案例,并使用互斥锁来确保线程安全。然后,…...
5、Ray-Actor模型和并发编程
5、Ray-Actor模型和并发编程 导航 1.简介和背景 2.Ray的基本概念和核心组件 3.分布式任务调度和依赖管理 4.对象存储和数据共享 5.Actor模型和并发编程 6.Ray的高级功能和扩展性 7.使用Ray构建分布式应用程序的案例研究 8.Ray社区和资源 9.核心框架介绍...

HNU-电路与电子学-小班2
第二次讨论 讨论题目: 1、电子秤的电桥电路可以分别用 1 个压控电阻、 2 个压控电阻、 3 个压控电阻、 4 个压控电阻实现吗?试写出每种实现的 U AB 输出表达式,并分析哪种实现电桥 电压的灵敏度(SV/ △ R )高。 …...
二分图匹配算法
匈牙利算法、Hopcroft-Karp算法和Kuhn-Munkres算法是三种常见的二分图匹配算法,它们在实现方式、时间复杂度和适用场景上有所差异。以下是它们的区别和优缺点: 匈牙利算法: 实现方式:匈牙利算法使用深度优先搜索(DFS)来寻找增广路…...

虹科技术 | 虹科EtherCAT增量编码器输入模块数据采集实操测试
1. 背景介绍 编码器是将信号或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号,前者称为码盘,后者称为码尺。按照读出方式编码器可以分为接触式和非接触式两种;按照工作原理编码器可分为…...

2023.05.21 学习周报
文章目录 摘要文献阅读1.题目2.背景3.现存问题和解决方法4.方法4.1 Variational mode decomposition (VMD)4.2 Bidirectional LSTM 5.实验5.1 数据标准化5.2 评价指标5.3 实验过程及结果 6.结论和展望 优劣解距离法有限元1.求解一个简单的传热问题2.有限元如何实现 总结 摘要 …...

资深程序员深度体验ChatGPT一周发现竟然....
周一打卡上班,老板凑到我跟前:“小李啊,这周有个新需求交给你做一下,给我们的API管理平台新增一个智能Mock的功能...”。我条件反射般的差点脱口而出:“这个需求做不了..”。不过在千钧一发之间,我想起了最…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...

实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...