b端产品架构怎么搭建(B端产品IAM-权限设计)
b端产品架构怎么搭建(B端产品IAM-权限设计)环境限制,分为三类:系统机制包括对主体、客体和主客体关系的认证,对主体行为及行为运行方式的授权。常见的机制有:指行为的行使者,是操作的发起者。主体的类型有很多种,常见的有:指行为的承受者,是操作所针对的对象。主要有三大类:指主体对客体的活动,包括主体在产品中对客体的一些操作,而我们常说的“权限”一词则指代了这一操作,例如“查看朋友圈的权限”。常见的行为有:
前言日常工作中权限的问题时时刻刻伴随着我们,程序员新入职一家公司需要找人开通各种权限,比如网络连接的权限、编码下载提交的权限、监控平台登录的权限、运营平台查数据的权限等等。在很多时候我们会觉得这么多繁杂的申请给工作带来不便,并且如果突然想要查一些数据,发现没有申请过权限,需要再走审批流程,时间拉得会很长。那为什么还需要这么严格的权限管理呢?
举个例子,一家支付公司有运营后台,运营后台可以查到所有的商户信息,法人代表信息,交易信息以及费率配置信息,如果我们把这些信息不加筛选都给到公司的每一个小伙伴,那么跑市场的都可以操作商家的费率信息,如果一个不小心把费率改了会造成巨大的损失。又比如商户的信息都是非常隐秘的,有些居心不良的小伙伴把这些信息拿出来卖给商家的竞争对手,会给商家造成严重的不良后果。虽然这么做都是个别人人为的过错,但是制度上如果本身这些信息不开放出来就能在很大程度上避免违法乱纪的事情发生了。
总体来讲权限管理是公司数据安全的重要保证,针对不同的岗位,不同的级别看到的数据是不一样的,操作数据的限制也是不一样的。比如涉及到资金的信息只开放给财务的相关岗位,涉及到配置的信息只开放给运营的相关岗位,这样各司其职能避免很多不必要的安全问题。如何让各个岗位的人在系统上各司其职,就是权限管理要解决的问题。
权限系统相关的四大要素权限是主体对客体遵循特定机制做出的行为。所以,权限的4个基本要素就是主体、客体、行为、机制。
1. 主体指行为的行使者,是操作的发起者。主体的类型有很多种,常见的有:
- 用户及用户组。更准确地术语应是“系统使用者”,其与系统的账号体系相对应,一个用户对应一个唯一账号;多个用户组成一个用户组;
- 角色及角色组。角色是权限分配的单位与载体,通常与组织架构体系相对应。Oracle产品中分为工作角色、职责角色、数据角色和抽象角色四类,后面我们会说到;
- 用户标签及用户标签组;
- 设备及设备组。HarmonyOS系统首期给Mate40系列开放使用;
- IP地址。限制对IP地址的访问;
- 地理位置。如O2O生活平台在不同位置展示的店铺不同;
- 局域网。如公司电脑在内网和外网所访问的资源不同。
指行为的承受者,是操作所针对的对象。主要有三大类:
(1)资源- 基本属性的数据
- 行数据
- 个别的列数据(俗称“某些字段”)
- 页面
- 目录或菜单
- Tab
- 按钮
- 任务流,也称工作流。某一资源在任务流中的状态不同,不同状态的资源可以分配给不同角色操作;
- 所属权。所属权包括个人、个人及下属、部门、部门及下属、全部,通常与组织架构体系的组织范围相对应。
指主体对客体的活动,包括主体在产品中对客体的一些操作,而我们常说的“权限”一词则指代了这一操作,例如“查看朋友圈的权限”。常见的行为有:
- 登入、登出
- 增
- 删
- 改,包括读写
- 查,包括不可见、只读
- 上传、下载
- 共享
- ……
系统机制包括对主体、客体和主客体关系的认证,对主体行为及行为运行方式的授权。常见的机制有:
- 继承:父级可以拥有子级的权限,依托于组织架构或角色层级结构;例如销售部门负责人有所有下属的权限;
- 互斥:是对主体之间责任的强制性规定,防止同一主体拥有足够权限进行欺骗行为,防止即当运动员又当裁判的行为。责任分离有静态和动态之分:
- 静态互斥:一个用户不能同时拥有两个互斥的角色。例如银行内部的贷款申请者和贷款审批者不能让同一个人承担;
- 动态互斥:一个用户可以拥有两个角色,但在运行时只能激活一个角色,也成为运行互斥机制。例如银行内部为了灵活放贷,职员张三可以同时有贷款申请者角色和贷款审批者角色,但对于同一笔贷款,不能即申请又审批。
- 先决条件:A想成为C,就必须先成为B,C只能从B中产生;
- 基数限制:是主体与主体、主体与客体、主体与行为间数量关系的限制。例如一个用户可拥有的角色数目受限;一个角色被分配的用户数量受限;一个角色的权限数目受限;
- 授予机制:是主体将自己的权限授予给其他主体的权限;
- 双向验证:系统即验证主体,也验证客体,双方都通过验证时才能允许主体对客体的行为;
- 共享机制:访问范围限定机制。一般有三类依托:
- 组织架构
- 角色层级结构
- 组织范围/抽象关系
环境限制,分为三类:
- 空间限制。例如针对地理位置、IP地址、局域网的限制;
- 时间限制。例如考试时间到了之后,操作权限有所限制;
- 频度限制。例如对输入密码的频率的限制;
Access Control List,ACL是最早的、最基本的一种访问控制机制,是基于客体进行控制的模型,在其他模型中也有ACL的身影。为了解决相同权限的用户挨个配置的问题,后来也采用了用户组的方式。
原理:每一个客体都有一个列表,列表中记录的是哪些主体可以对这个客体做哪些行为,非常简单。
例如:当用户A要对一篇文章进行编辑时,ACL会先检查一下文章编辑功能的控制列表中有没有用户A,有就可以编辑,无则不能编辑。再例如:不同等级的会员在产品中可使用的功能范围不同。阿里巴巴集团内部的权限管控采用的就是ACL,每个用户可以根据自己需求申请相应的权限。
缺点:当主体的数量较多时,配置和维护工作就会成本大、易出错。
2. DAC模型:自主访问控制Discretionary Access Control,DAC是ACL的一种拓展。
原理:在ACL模型的基础上,允许主体可以将自己拥有的权限自主地授予其他主体,所以权限可以任意传递。
例如:常见于文件系统,LINUX,UNIX、WindowsNT版本的操作系统都提供DAC的支持。
缺点:对权限控制比较分散,例如无法简单地将一组文件设置统一的权限开放给指定的一群用户。主体的权限太大,无意间就可能泄露信息。
3. MAC模型:强制访问控制Mandatory Access Control,MAC模型中主要的是双向验证机制。常见于机密机构或者其他等级观念强烈的行业,如军用和市政安全领域的软件。
原理:主体有一个权限标识,客体也有一个权限标识,而主体能否对该客体进行操作取决于双方的权限标识的关系。
例如:将军分为上将>中将>少将,军事文件保密等级分为绝密>机密>秘密,规定不同军衔仅能访问不同保密等级的文件,如少将只能访问秘密文件;当某一账号访问某一文件时,系统会验证账号的军衔,也验证文件的保密等级,当军衔和保密等级相对应时才可以访问。
缺点:控制太严格,实现工作量大,缺乏灵活性。
4. RBAC模型:基于角色的访问控制(Role-Based Access Control),RBAC模型在目前使用的最广泛、最普遍。
原理:在主体和权限之间引入了“角色(Role)”的概念,角色解耦了主体和权限之间的关系。,有四个不同的层次:
- RBAC0:基本模型,相当于ACL 角色。权限被赋予角色,而不是用户,当一个角色被制定给一个用户时,该用户就拥有了该角色所包含的权限。所有的角色都是平级的,没有制定角色层级关系;所有对象都没有附加约束,没有制定限制;
- RBAC1:角色分级模型,相当于RBAC0 继承机制;
- RBAC2:角色限制模型,相当于RBAC0 互斥机制 先决条件机制 基数限制机制;
- RBAC3:统一模型,相当于RBAC1 RBAC2。
缺点:需要将某个权限单独设置给用户时,如果用户已有的角色中不包含该权限,就需要重新设置角色的权限或者重新创建一个新的角色,在业务和需求变更时需要维护大量的角色。
5. ABAC模型:基于属性的访问控制(Attribute-Based Access Control),能很好地解决RBAC的缺点,在新增资源时容易维护。
原理:通过动态计算一个或一组属性是否满足某种机制来授权,是一种很灵活的权限模型,可以按需实现不同颗粒度的权限控制。
属性通常有四类:
- 一是主体属性,如用户年龄、性别等;
- 二是客体属性,如一篇文章等;
- 三是环境属性,即空间限制、时间限制、频度限制;
- 四是操作属性,即行为类型,如读写、只读等。
例如:早上9:00~11:00期间A、B两个部门一起以考生的身份考试,下午14:00~17:00期间A、B两个部门相互阅卷。另外云产品的权限设计一版都采用ABAC权限模型,例如AWS的IAM以及阿里云的RAM。
缺点:规则复杂,不易看出主体与客体之间的关系,实现非常难,现在应用的很少。
RBAC权限模型RBAC 模型可以分为:RBAC0、RBAC1、RBAC2、RBAC3 四个阶段,一般公司使用 RBAC0 的模型就可以。另外,RBAC0 相当于底层逻辑,后三者都是在 RBAC0 模型上的拔高。
我先简单介绍下这四个 RBAC 模型:
RBAC0权限模型用户和角色、角色和权限多对多关系。
简单来说就是一个用户拥有多个角色,一个角色可以被多个用户拥有,这是用户和角色的多对多关系;同样的,角色和权限也是如此。
RBAC0 模型如下图:没有画太多线,但是已经能够看出多对多关系。
用户 是发起操作的主体 按类型分可分为2B和2C用户 可以是后台管理系统的用户 可以是OA系统的内部员工 也可以是面向C端的用户 比如阿里云的用户。
角色 起到了桥梁的作用 连接了用户和权限的关系 每个角色可以关联多个权限 同时一个用户关联多个角色 那么这个用户就有了多个角色的多个权限。
权限是用户可以访问的资源 包括页面权限 操作权限 数据权限:
- 页面权限: 即用户登录系统可以看到的页面 由菜单来控制 菜单包括一级菜单和二级菜单 只要用户有一级和二级菜单的权限 那么用户就可以访问页面
- 操作权限: 即页面的功能按钮 包括查看 新增 修改 删除 审核等 用户点击删除按钮时 后台会校验用户角色下的所有权限是否包含该删除权限 如果是 就可以进行下一步操作 反之提示无权限。
有的系统要求"可见即可操作" 意思是如果页面上能够看到操作按钮 那么用户就可以操作
要实现此需求 这里就需要前端来配合 前端开发把用户的权限信息缓存 在页面判断用户是否包含此权限 如果有 就显示该按钮 如果没有 就隐藏该按钮。某种程度上提升了用户体验 但是在实际场景可自行选择是否需要这样做 - 数据权限: 数据权限就是用户在同一页面看到的数据是不同的 比如财务部只能看到其部门下的用户数据 采购部只看采购部的数据
在一些大型的公司 全国有很多城市和分公司 比如杭州用户登录系统只能看到杭州的数据 上海用户只能看到上海的数据 解决方案一般是把数据和具体的组织架构关联起来
相对于 RBAC0 模型,增加了角色分级的逻辑,类似于树形结构,下一节点继承上一节点的所有权限,如 role1 根节点下有 role1.1 和 role1.2 两个子节点
角色分级的逻辑可以有效的规范角色创建(主要得益于权限继承逻辑),比如在CRM系统中,BD 之间就有分级(经理、主管、专员),如果采用 RBAC0 模型做权限系统,我可能需要为经理、主管、专员分别创建一个角色(角色之间权限无继承性),极有可能出现一个问题,由于权限配置错误,主管拥有经理都没有权限。
而 RBAC1 模型就很好解决了这个问题,创建完经理角色并配置好权限后,主管角色的权限继承经理角色的权限,并且支持针对性删减主管权限。
而受限继承关系则进一步要求角色继承关系是一个树结构,实现角色间的单继承。这种设计可以给角色分组和分层,一定程度简化了权限管理工作。
RBAC2权限模型(约束限制)基于 RBAC0 模型,对角色增加了更多约束条件。
如角色互斥,比较经典的案例是财务系统中出纳不得兼管稽核,那么在赋予财务系统操作人员角色时,同一个操作员不能同时拥有出纳和稽核两个角色。
如角色数量限制,例如:一个角色专门为公司 CEO 创建的,最后发现公司有 10 个人拥有 CEO 角色,一个公司有 10 个 CEO?这就是对角色数量的限制,它指的是有多少用户能拥有这个角色。
如先决条件角色:,即用户想获得某上级角色 必须先获得其下一级的角色。
RBAC2 模型主要是为了增加角色赋予的限制条件,这也符合权限系统的目标:权责明确,系统使用安全、保密。
RBAC3 模型同样是基于 RBAC0 模型,但是综合了 RBAC1 和 RBAC2 的所有特点,是功能最全的模型,也是各大公司最常用的一种模型。我们平时见到的权限管理,一般是和公司的组织架构是一一对应的。
这里就不在多描述,读者返回去看 RBAC1 和 RBAC2 模型的描述即可。
RBAC权限设计用户管理用户管理中的用户,是企业里每一位员工,他们本身就有自己的组织架构,我们可以直接使用企业部门架构或者业务线架构来作为线索,构建用户管理系统。
需要特殊注意:实际业务中的组织架构可能与企业部门架构、业务线架构不同,需要考虑数据共享机制,一般的做法为授权某个人、某个角色组共享某个组织层级的某个对象组数据。
用户组我们创建角色是为了解决用户数量大的情况下,用户分配权限繁琐以及用户-权限关系维护成本高的问题。抽象出一个角色,把需要一起操作的权限分配给这个角色,把角色赋予用户,用户就拥有了角色上的权限,这样避免了一个个的给用户分配权限,节省了大量的资源。同样的如果有一批用户需要相同的角色,我们也需要一个个的给用户分配角色,比如一个公司的客服部门有500多个人,有一天研发部研发了一套查询后台数据的产品,客服的小伙伴都需要使用,但是客服由于之前并没有统一的一个角色给到所有的客服小伙伴,这时候需要新加一个角色,把权限分配给该角色,然后再把角色一个个分配给客服人员,这时候会发现给500个用户一个个添加角色非常的麻烦。但是客服人员又有共同的属性,所以我们可以创建一个用户组,所有的客服人员都属于客服用户组,把角色分配给客服用户组,这个用户组下面的所有用户就拥有了需要的权限。RBAC模型添加用户组之后的模型图如下所示:
很多朋友会问,用户组和角色有什么区别呢?简单的来说,用户组是一群用户的组合,而角色是用户和权限之间的桥梁。用户组把相同属性的用户组合起来,比如同一个项目的开发、产品、测试可以是一个用户组,同一个部门的相同职位的员工可以是一个用户组, 一个用户组可以是一个职级,可以是一个部门,可以是一起做事情的来自不同岗位的人。
用户可以分组,权限也可以分组,权限特别多的情况下,可以把一个模块的权限组合起来成为一个权限组,权限组也是解决权限和角色对应关系复杂的问题。比如我们定义权限的时候一级菜单、二级菜单、按钮都可以是权限,一个一级菜单下面有几十个二级菜单,每个二级菜单下面又有几十个按钮,这时候我们把权限一个个分配给角色也是非常麻烦的,可以采用分组的方法把权限分组,然后把分好的组赋予角色就可以了。给权限分组也是个技术活,需要理清楚权限之间的关系,比如支付的运营后台我们需要查各种信息,账务的数据、订单的数据、商户的数据等等,这些查询的数据并不在一个页面,每个页面也有很多按钮,我们可以把这几个页面以及按钮对应的权限组合成一个权限组赋予角色。加入权限组之后的RBAC模型如下所示:
实际工作中我们很少给权限分组,给用户分组的场景会多一些,有的时候用户组也可以直接和权限关联,这个看实际的业务场景是否需要,权限模型没有统一的,业务越复杂业务模型会约多样化。
组织常见的组织架构如下图:
我们可以把组织与角色进行关联 用户加入组织后 就会自动获得该组织的全部角色 无须管理员手动授予 大大减少工作量 同时用户在调岗时 只需调整组织 角色即可批量调整。
定义组织有哪些优势:
实现权限分配的自动化
和组织关系打通之后,按照组织来分配角色,如果有新入职的用户,被划分在某个组织下面之后,会自动获取该组织下所有的权限,无需人工分配。又比如有用户调岗,只需要把组织关系调整就可以了,权限会跟着组织关系自动调整,也无需人工干预。这么做首先需要把权限和组织关系打通。
控制数据权限
把角色关联到组织,组织里的成员只能看到本组织下的数据。
职位假设财务部的职位如下图:
一个组织下面会有很多职位,比如财务管理会有财务总监、财务主管、会计、出纳员等职位,每个职位需要的权限是不一样的,总监拥有所有权限 会计和出纳拥有部分权限,可以像组织那样根据职位来分配不同的角色,由于一个人的职位是固定的(特殊情况下 一个人可能身兼多职),所以用户跟职位的对应关系时一对一的关系,职位跟角色的对应关系可以是多对多的关系。加入职位的RBAC模型如下所示:
含有组织/职位/用户组的模型根据以上场景 新的权限模型就可以设计出来了 如下图:
根据系统的复杂度不同 其中的多对多关系和一对一关系可能会有变化
- 在单系统且用户类型单一的情况下 用户和组织是一对一关系 组织和职位是一对多关系 用户和职位是一对一关系 组织和角色是一对一关系 职位和角色是一对一关系 用户和用户组是多对对关系 用户组和角色是一对一关系 当然这些关系也可以根据具体业务进行调整。模型设计并不是死的 如果小系统不需要用户组 这块是可以去掉的。
- 分布式系统且用户类型单一的情况下 到这里权限系统就会变得很复杂 这里就要引入了一个"系统"概念 此时系统架构是个分布式系统 权限系统独立出来 负责所有的系统的权限控制 其他业务系统比如商品中心 订单中心 用户中心 每个系统都有自己的角色和权限 那么权限系统就可以配置其他系统的角色和权限。
- 分布式系统且用户类型多个的情况下 比如淘宝网 它的用户类型包括内部用户 商家 普通用户 内部用户登录多个后台管理系统 商家登录商家中心 这些做权限控制 如果你作为架构师 该如何来设计呢?
授权即给用户授予角色 按流程可分为手动授权和审批授权。权限中心可同时配置这两种 可提高授权的灵活性。
- 手动授权
管理员登录权限中心为用户授权 根据在哪个页面授权分为两种方式:给用户添加角色 给角色添加用户。给用户添加角色就是在用户管理页面 点击某个用户去授予角色 可以一次为用户添加多个角色;给角色添加用户就是在角色管理页面 点击某个角色 选择多个用户 实现了给批量用户授予角色的目的。
- 审批授权
即用户申请某个职位角色 那么用户通过OA流程申请该角色 然后由上级审批 该用户即可拥有该角色 不需要系统管理员手动授予。
角色管理在设计系统角色时,我们应该深入理解公司架构、业务架构后,再根据需求设计角色及角色内的等级。
一般角色相对于用户来说是固定不变的,每个角色都有自己明确的权限和限制,这些权限在系统设计之处就确定了,之后也轻易不会再变动。
1. 自动获得基础角色当员工入职到某部门时,该名员工的账号应该自动被加入该部门对应的基础角色中,并拥有对应的基础权限。这种操作是为了保证系统安全的前提下,减少了管理员大量手动操作。使新入职员工能快速使用系统,提高工作效率。
2. 临时角色与失效时间公司业务有时需要外援来支持,他们并不属于公司员工,也只是在某个时段在公司做支持。此时我们需要设置临时角色,来应对这种可能跨多部门协作的临时员工。
如果公司安全级别较高,此类账号默认有固定失效时间,到达失效时间需再次审核才能重新开启。避免临时账号因为流程不完善,遗忘在系统中,引起安全隐患。
3. 虚拟角色部门角色中的等级,可以授权同等级的员工拥有相同的权限,但某些员工因工作原因,需要调用角色等级之外的权限,相同等级不同员工需要使用的权限还不相同。
这种超出角色等级又合理的权限授予,我们可以设置虚拟角色。这一虚拟角色可集成这一工作所需的所有权限,然后将它赋予具体的员工即可。这样即不用调整组织架构和对应的角色,也可以满足工作中特殊情况的权限需求。
4. 黑白名单白名单:某些用户自身不拥有某部门的顶级角色,但处于业务需求,需要给他角色外的高级权限,那么我们可以设计限制范围的白名单,将需要的用户添加进去即可。
在安全流程中,我们仅需要对白名单设计安全流程,即可审核在白名单中的特殊用户,做到监控拥有特殊权限的用户,减少安全隐患。
黑名单:比较常见的黑名单场景是某些犯了错误的员工,虽然在职,但已经不能给他们任何公司权限了。这种既不能取消角色关联,也不能完全停用账号的情况,可以设置黑名单,让此类用户可以登录账号,查看基本信息,但大多数关键权限已经被黑名单限制。
权限管理权限管理一般从三个方面来做限制。页面/菜单权限,操作权限,数据权限。
1. 页面/菜单权限对于没有权限操作的用户,直接隐藏对应的页面入口或菜单选项。这种方法简单快捷直接,对于一些安全不太敏感的权限,使用这种方式非常高效。
2. 操作权限操作权限通常是指对同一组数据,不同的用户是否可以增删改查。对某些用户来说是只读浏览数据,对某些用户来说是可编辑的数据。
3. 数据权限对于安全需求高的权限管理,仅从前端限制隐藏菜单,隐藏编辑按钮是不够的,还需要在数接口上做限制。如果用户试图通过非法手段编辑不属于自己权限下的数据,服务器端会识别、记录并限制访问。
4. 数据权限如何管控数据权限可以分为行权限和列权限。行权限控制:看多少条数据。列权限控制:看一条数据的多少个字段
简单系统中可以通过组织架构来管控行权限,按照角色来配置列权限,但是遇到复杂情况,组织架构是承载不了复杂行权限管控,角色也更不能承载列的特殊化展示。
目前行业的做法是提供行列级数据权规则配置,把规则当成类似权限点配置赋予某个角色或者某个用户。
数据库表结构设计标准版RBAC表结构设计有了角色之后可以把权限分配给角色,需要相同权限的用户和角色对应起来就可以了,一个权限可以分配给多个角色,一个角色可以拥有多个权限,同样一个用户可以分配多个角色,一个角色也可以对应多个用户,标准版对应模型如下所示:
这就是经典的RBAC模型了(role-based-access-control),在这里面角色起到了桥梁左右,连接了用户和权限的关系,每个角色可以拥有多个权限,每个用户可以分配多个角色,这样用户就拥有了多个角色的多个权限。同时因为有角色作为媒介,大大降低了错综复杂的交互关系,比如一家有上万人的公司,角色可能只需要几百个就搞定了,因为很多用户需要的权限是一样的,分配一样的角色就可以了。
标准RBAC模型的表是比较简单了,要表示用户-角色-权限三者之前的关系,首先要创建用户表、角色表、权限表,用户和角色是多对多的关系,角色和权限是多对多的关系,需要再创建两章关系表,分别是用户-角色关系表和角色-权限关系表。这六张表的ER图如下所示:
通用版RBAC表结构设计RBAC模型根据不同业务场景的需要会有很多种演变,实际工作中业务是非常复杂的,权限分配也是非常复杂的,想要做出通用且高效的模型很困难。我们把RBAC模型的演变汇总起来会是一个支撑大数据量以及复杂业务的理想的模型。把RBAC、RBAC1、RBAC2、用户组、组织、职位汇总起来的模型如下所示:
按照这个模型基本上能够解决所有的权限问题,其中的对应关系可以根据实际的业务情况来确定,一般情况下,组织和职位是一对多的关系,特殊情况下可以有多对多的情况,需要根据实际情况来定。
通用RBAC模型并不是说我们一开始建权限模型就可以这么做,而是数据体量、业务复杂度达到一定程度之后可以使用这个模型来解决权限的问题,如果数据量特别少,比如刚成立的公司只有十几个人,那完全可以用用户-权限模型,都没有必要使用RBAC模型。
通用RBAC模型是标准RBAC模型经过多次扩展得到的,表结构也会比较复杂,因为要维护很多关系,如下图所示是理想的RBAC模型的ER图:
权限框架- Apache Shrio
- Spring Security
在项目中可以采用其中一种框架 它们的优缺点以及如何使用会在后面的文章中详细介绍,本章节不做具体介绍。
ABAC权限设计ABAC概述基于属性的访问控制(Attribute-Based Access Control,简称 ABAC)是一种非常灵活的授权模型,不同于 RBAC,ABAC 则是通过各种属性来动态判断一个操作是否可以被允许。这个模型在如今的云系统中使用的比较多,比如AWS,阿里云,腾讯云,京东云等,它们都是用ABAC来管控IaaS以及PaaS的资源,曾经K8s也使用过这个模型来进行权限管控。
我们上面说过,RBAC的能力可以用这么一句话来描述:一个用户通过和角色绑定,具备了一些对数据操作的能力,往简单的说就是一个用户有了一些对数据操作的能力。但是,如果在复杂的权限管控场景中,RBAC显得有些力不从心,比如说:
- 用户在晚上不能访问这个系统,但是白天可以
- 用户只能在内网对订单具备修改权限,而在外网就只有查看权限
- 用户对2021-03-19日之前创建的订单有操作权限
- 用户只能在深圳进行查看订单,而去了国外就不可以
- 用户在公司内部可以访问所有数据,但是在外部就只能访问公开数据 我们很容易就发现,RBAC仅仅描述了用户可以做什么操作,但是操作的条件,以及操作的数据,模型本身是没有这些限制的,这也是由于其模型能力的不足所导致的,但这却恰恰是ABAC的长处,ABAC的思想是基于用户、以及将要访问的数据的属性、以及各种环境因素去动态计算用户是否有权限进行操作。
在 ABAC 中,一个操作是否被允许是基于对象、资源、操作和环境信息共同动态计算决定的。
- 对象:对象是当前请求访问资源的用户。用户的属性包括ID,个人资源,角色,部门和组织成员身份等;
- 资源:资源是当前访问用户要访问的资产或对象(例如文件,数据,服务器,甚至API)。资源属性包含文件的创建日期,文件所有者,文件名和类型以及数据敏感性等等;
- 操作:操作是用户试图对资源进行的操作。常见的操作包括“读取”,“写入”,“编辑”,“复制”和“删除”;
- 环境:环境是每个访问请求的上下文。环境属性包含访问尝试的时间和位置,对象的设备,通信协议和加密强度等。
在 ABAC 的决策语句的执行过程中,决策引擎会根据定义好的决策语句,结合对象、资源、操作、环境等因素动态计算出决策结果。、
每当发生访问请求时,ABAC 决策系统都会分析属性值是否与已建立的策略匹配。如果有匹配的策略,访问请求就会被通过。
例如,策略「当一个文档的所属部门跟用户的部门相同时,用户可以访问这个文档」会被以下属性匹配:
- 对象(用户)的部门 = 资源的所属部门;
- 资源 = “文档”;
- 操作 = “访问”;
策略「早上九点前禁止 A 部门的人访问B系统;」会被以下属性匹配:
- 对象的部门 = A 部门;
- 资源 = “B 系统”;
- 操作 = “访问”;
- 环境 = “时间是早上 9 点”。
在 ABAC 权限模型下,你可以轻松地实现以下权限控制逻辑:
- 授权 A 具体某部门的编辑权限;
- 当一个文档的所属部门跟用户的部门相同时,用户可以访问这个文档;
- 当用户是一个文档的拥有者并且文档的状态是草稿,用户可以编辑这个文档;
- 早上九点前禁止 A 部门的人访问 B 系统;
- 在除了上海以外的地方禁止以管理员身份访问 A 系统;
上述的逻辑中有几个共同点:
- 具体到某一个而不是某一类资源;
- 具体到某一个操作;
- 能通过请求的上下文(如时间、地理位置、资源 Tag)动态执行策略;
如果浓缩到一句话,你可以 细粒度地授权在何种情况下对某个资源具备某个特定的权限。
ABAC的权限模型在 ABAC 中有几个概念:
- 用户:你的终端用户;
- 角色:角色是一个逻辑集合,你可以授权一个角色某些操作权限,然后将角色授予给用户,该用户将会继承这个角色中的所有权限;
- 资源:你可以把你应用系统中的实体对象定义为资源,比如订单、商品、文档、书籍等等,每种资源都可以定义多个操作,比如文档有阅读、编辑、删除操作;
- 授权:把某类(个)资源的某些(个)操作授权给角色或者用户。
在 ABAC的权限系统中,我们通过用户、角色这两种对象实现了 RBAC 模型的角色权限继承,在此之上,我们还能围绕属性进行动态地、细粒度地授权,从而实现了 ABAC 权限模型。同时,我们为了满足大型系统中复杂组织架构的设计需求,将资源、角色、权限授权统一组合到一个权限分组中,方便开发者进行管理。
ABAC最佳实践NIST ABAC权限模型我们先简单介绍一下NIST ABAC设计指引中的一些术语:
- subject 指的是系统的使用者,可以是用户(user) 也可以是其他非服务的个体(non-person entity,NPE)
- object 泛指被访问的数据
- operation/action 指操作行为,一般对应系统中的API
- policy 访问策略,它规定了一个用户在什么条件下可以对哪些数据做什么,是ABAC系统核心实体之一
- pdp pdp是policy decision point,策略点,其实我理解这玩意就是一个policy的展示出来的形式而已
- pep pep是policy enforcement point 策略执行点,简单说就是根据policy来鉴权
- acm acm是access control mechanism 权限管控机制,一般来说就是权限系统本身
- attribute 它泛指各种属性,可以是subject的,也可以是object的
- condition 各种额外的限制条件 NIST的文章中,下图描述了上面术语之间的关系:
很容易发现,ABAC仅仅受限于可以用来计算的属性的数量,这也很容易让很多人产生误解,误认为ABAC什么类型的权限都可以来管控,事实上,权限系统仅仅擅长于管控垂直越权,即使ABAC具备一定的管控水平越权的能力,也不要妄想可以用它来管控所有的水平越权。
简版ABAC模型设计AWS IAM产品应该是IAM产品中的业界标杆,其权限设计也是采用的ABAC权限模型,以下相关IAM权限模型设计参考了AWS IAM的相关设计。
设计思路最简单的IAM系统应该包括:
- 管理模块
- 鉴权模块
管理模块:管理IAM中需要的数据和实体,比如:用户管理、组管理、角色管理、策略管理。
鉴权模块:基于ABAC模型的策略鉴权方式。
策略是一个重要的元素。
策略是 IAM 中的对象;在与身份或资源相关联时,策略定义它们的权限。在委托人使用 IAM 实体(如用户或角色)发出请求时, 服务将评估这些策略。策略中的权限确定是允许还是拒绝请求。
一个策略大概是长这样:
{
"Version": "2012-10-17"
"Statement": {
"Effect": "Allow"
"Action": "dynamodb:*"
"Resource": "arn:aws:dynamodb:us-east-2:123456789012:table/Books"
"Condition":""
}
}
策略其实就是我们制定的权限规则。策略与某个实体(例如用户)绑定在一起,当用户进行访问请求时,会检查拥有的策略进行匹配,匹配成功,则响应对应的操作,匹配失败则说明没有权限。
在RBAC中的鉴权流程是: 角色是否有权限。
在IAM ABAC中的鉴权流程是:请求是否匹配了策略。
由于策略的制定是非常灵活的,也就是ABAC的权限模型比RBAC权限模型更能满足灵活和复杂的场景的原因。
这个最简单的IAM系统是将两个模块需要的接口设计好,开发完成,通过手动组装参数(Postman)调用接口能够调通。对于整个IAM系统来说,只是完成了其中的一环,还有其他重要的部分:网关和底层数据系统。
在网关进行鉴权是大部分系统的选择方案。底层鉴权模式改了,原来存在的各种鉴权类型都需要能够兼容。所以,网关鉴权的改造是重要的一环。
当请求到达网关,网关需要做的事情是根据请求的参数,能够得到对应的实体(比如用户),将鉴权需要的所有信息准备好,然后调用IAM服务的接口,进行权限校验。如果成功,则将请求转发到具体业务,失败,则返回没有操作权限错误。
底层数据系统一般包含这些:
- 产品数据系统
- 接口数据系统
- 资源数据系统
- 属性数据系统
一个功能强大的IAM系统需要这些底层数据系统的支持。IAM系统中的关键对象是策略,它决定着ABAC的鉴权方式。而策略中的组成对象Action、Resource和Condition中的定义,就是来源于产品、接口、资源、属性,下面具体讲解。
鉴权示例可以这样理解:用户进行产品操作是通过调用接口的方式操作某资源进行增、删、改、查。
先一起了解一下在IAM服务是如何鉴权的。
假设网关准备好了参数传递给了IAM服务,IAM服务进行:
- 查找对应的策略
- 匹配Action
- 匹配Resource
- 匹配Condition(如果有配置)
如下图:
我们发起了一个接口请求 参数是这样的:
{
"Action": "UpdateUFileName"
"Name": "aaabbb"
"ObjectID": 1
}
在鉴权的时候,假设查找到了唯一的对应的策略A。就需要将请求参数中的Action和策略A中的Action进行匹配(这里请求没有传Resource参数,所以不用匹配),如果匹配成功,就会执行Effect定义的相应Allow允许或Deny拒绝操作,如果没有匹配成功也是拒绝。
如果只是”完全相等”的匹配,对于底层数据的支持要求很低,但这种匹配是无法实现灵活的功能的。
如果需要灵活方式的匹配,对于底层数据的支持要求很高。
在AWS 的策略定义中是支持通配符匹配的,比如:"Action": "dynamodb:*"。
接口设计,资源设计没有任何制定的规范规则,如何在策略定义中支持通配符匹配呢?
策略的定义是可以实现很灵活的匹配以满足实际需求,然而灵活并非无规则、无序。
假设我们这样规范一个接口的名称: 操作 产品 其他。拆解一下UpdateUFileName接口
- 操作:Update
- 产品:UFile
- 其他:Name
通过接口名称就能知道是什么操作了具体哪款产品。在策略中不就可以制定通配符匹配的规则了嘛。
{
"Version": "2012-10-17"
"Statement": {
"Effect": "Allow"
"Action": "UFile:Update*"
}
}
策略表示:UFile 产品的所有更新接口操作都允许。
同理Resource需要资源数据系统的支持。
IAM权限系统需要产品数据系统、接口数据系统、资源数据系统、属性数据系统的支持(根据自身匹配业务的需求来确定需要哪些底层数据系统的支持)。如果没有,强烈建议先进行底层数据系统的设计。
IAM系统涉及的系统架构
我们知道,关于匹配算法,正则匹配会是第一个想到的方案,正则匹配的功能太强大了。但是,正则匹配功能强大,匹配性能很可能较低。由于策略的匹配是很频繁的操作,对性能有较高要求,基于通配符匹配库glob和正则匹配的一个benchmark,是一个不错的方案。
扩展思考非中心化的鉴权方式。
中心化的鉴权方式:网关与鉴权服务集群通信后,再将请求转到具体业务方服务。如果这个鉴权服务集群挂了,整个业务就不通了。
非中心化的鉴权方式:以SDK的方式,在每个业务方进行鉴权。这样,各个业务方服务是互不影响的。但是使用SDK的方式,会带来SDK管理使用的问题,比如:不同业务方技术栈的不同,使得需要提供多种技术语言的SDK实现。SDK升级的时候,需要考虑老版本,以及每个技术语言的SDK都需要升级,在大版本升级无法兼容旧版本的情况,还需要协调所有业务方都升级,这边也是一个不小的维护工作量。
目前个人觉得,中心化的集群方式对于服务端开发来说是更合理的方式。如果请求量逐渐增加,系统性能瓶颈出现,那么选择增加服务器和集中优化系统性能让系统保持稳定。
总结权限模型选择关于权限模型选择,组织的规模是至关重要的因素。由于 ABAC 最初的设计和实施困难,对于小型企业而言,考虑起来可能太复杂了。
对于中小型企业,RBAC 是 ABAC 的简单替代方案。每个用户都有一个唯一的角色,并具有相应的权限和限制。当用户转移到新角色时,其权限将更改为新职位的权限。这意味着,在明确定义角色的层次结构中,可以轻松管理少量内部和外部用户。
但是,当必须手动建立新角色时,对于大型组织而言,效率不高。一旦定义了属性和规则,当用户和利益相关者众多时,ABAC 的策略就更容易应用,同时还降低了安全风险。
简而言之,如果满足以下条件,请选择 ABAC:
- 你在一个拥有许多用户的大型组织中;
- 你需要深入的特定访问控制功能;
- 你有时间投资远距离的模型;
- 你需要确保隐私和安全合规;
但是,如果满足以下条件,请考虑 RBAC:
- 你所在的是中小型企业;
- 你的访问控制策略广泛;
- 你的外部用户很少,并且你的组织角色得到了明确定义;
超级管理员是用来启动系统,配置系统的账号。这个账号应该在配置好系统,创建管理员之后被隐藏起来。超级管理员账号拥有系统中全部权限,可穿梭查看各部门数据,如果使用不恰当,是系统管理的安全隐患。
2.互斥角色如何处理当用户已经有用的角色和即将添加的角色互相互斥时,应该在添加新角色时,提示管理员因角色互斥的原因,无法进行新角色添加。如需添加,要先撤销掉前一个角色,再添加新角色。
3.用户管理权限系统设计一定要简单清晰在设计权限系统之处,一定要理清思路,一切从简,能不增加的多余角色和权限逻辑,就一定不要增加。因为随着公司业务的扩大,权限和角色也会随之增多,如果初期设计思路不严谨,那么权限系统会随着业务的扩大而无限混乱下去,此时再来整理权限,已经太晚了。所以初期设计就一定要条理清晰,简单明了,能避免后续非常多不必要的麻烦。
4.无权提示页有时员工 A 会直接给员工 B 分享他当下正在操作的页面,但有可能员工 B 无权查看。此时我们应该在这里考虑添加「无权提示页」,避免粗暴的 404 页面让员工 B 以为是系统出错了。