1、ABAC 概述与核心概念

说起权限模型,大家第一反应多半是 RBAC。但我做了七八年安全架构,真正让我觉得“好用”的,其实是 ABAC。说白了,ABAC 就是“看人下菜碟”——用户能不能干某件事,不只看他是什么角色,还要看他、资源、环境甚至操作本身的各种属性。

一句话总结:ABAC 是 Attribute-Based Access Control,属性驱动。权限决策完全基于实体属性和环境属性,而非固定角色。

什么是 ABAC

ABAC 全称 Attribute-Based Access Control,中文叫基于属性的访问控制。它的核心思想是:用属性来描述用户、资源、操作和环境,然后通过策略引擎来计算这些属性组合是否满足条件。

举个例子,你在一个系统里想查看订单详情。在 ABAC 下,策略可能写成:

// 伪代码示例:ABAC 策略
PERMIT ACCESS TO resource:order
WHEN
  user.department == resource.department
  AND user.clearance_level >= resource.security_level
  AND environment.time BETWEEN '09:00' AND '18:00'

你看,这里用了三个属性:用户部门、资源部门、用户安全等级、资源安全等级、当前时间。每个属性都是动态的,可以随时变化。

经验之谈:我在项目中遇到过客户说“我们需求很复杂,RBAC 搞不定”。其实很多时候他们需要的不是更复杂的角色继承,而是 ABAC 这种按属性动态计算的方式。ABAC 的灵活度远超 RBAC,但复杂度也相应上升。

属性驱动访问控制

ABAC 里的“属性”通常分为四类:

  • 用户属性:比如部门、职级、安全等级、所在国家、年龄、登录方式等。
  • 资源属性:比如文档分类、密级、创建者、所属项目、存储位置等。
  • 操作属性:比如读取、写入、删除、导出、执行等。
  • 环境属性:比如当前时间、IP 段、设备类型、网络状态、登录频率等。

决策引擎拿到这四类属性后,跟预先定义的策略集合逐一比对,最终输出 Permit 或 Deny。整个过程无需提前分配角色,完全由属性驱动。

我曾经遇到一个坑:某团队把用户属性硬编码到策略里,结果换部门就得改策略。正确的做法是 属性应该来自统一属性源(比如 LDAP、IDP、CMDB),策略只关心属性名和条件。

注意:属性值的来源必须可信且一致。如果同一个“部门”从两个系统拿到的值不同,决策就会出错。建议搭建属性服务层做归一化。

ABAC 与 RBAC 的异同

RBAC 大家都很熟了——角色(Role)是访问控制的核心。用户归属角色,角色绑定权限。而 ABAC 没有角色的概念,只有属性。

但 ABAC 并不完全替代 RBAC,更多时候是互补。下面这张表可以帮你快速理解差异:

对比维度 RBAC ABAC
权限粒度 粗粒度,基于角色 细粒度,基于属性表达式
动态性 静态,角色变更需要管理员操作 动态,属性变化立即影响权限
可扩展性 角色爆炸问题,每增加一种权限组合就可能需要新角色 属性可以任意组合,不会产生角色膨胀
上下文感知 不支持 天然支持(时间、地点、设备等)
策略复杂度 低,容易理解 高,需要专业策略引擎和表达式语言
性能 快,直接查角色-权限映射表 相对较慢,需要实时解析属性并执行策略
适用场景 组织架构稳定、权限变化少 多租户、数据安全等级高、权限随上下文变化

我个人的习惯是:能用 RBAC 搞定的就用 RBAC,搞不定的时候再加一层 ABAC。比如公司内部 OA 系统,角色清晰且变化少,用 RBAC 足够。但如果你做的是 SaaS 平台,每个租户有自定义属性规则,那 ABAC 几乎是必选项。

核心结论:ABAC 是 RBAC 的超集,并不是替代关系。把 ABAC 当作一个增强层,放在 RBAC 之上,既能保留角色管理的简洁性,又能获得属性级的灵活控制。
ABAC 属性驱动访问控制逻辑 用户属性 资源属性 操作属性 环境属性 策略决策引擎 Permit / Deny 属性来自 LDAP/IDP 属性来自 CMDB/标签 策略集 (Policy Set)

上图展示的是 ABAC 的完整决策链路。四个属性维度输入到策略引擎,引擎根据预置的策略集实时计算,最终输出 Permit 或 Deny。我在项目里把这个图贴在项目白板上,团队立马就理解了 ABAC 的运作方式。

小建议:如果你刚开始接触 ABAC,可以从一个简单的场景入手——比如“只允许本部门员工在上班时间查看本部门的文档”。把这个规则翻译成属性表达式,你就会发现 ABAC 的思路非常自然。