1. ABAC概述:定义、核心概念、与RBAC/DAC对比

说起访问控制,很多人的第一反应就是 RBAC(基于角色的访问控制)。但干了这么多年安全架构,我得说:RBAC 在某些场景下真的不够用。今天我们就来聊聊 ABAC——基于属性的访问控制。它不是什么新鲜概念,但这两年随着微服务和零信任架构的普及,ABAC 又重新回到了舞台中央。

什么是 ABAC?先看一个真实案例

我曾经接手过一个金融系统的权限改造项目。客户的要求很简单:“员工只能查看自己所在分支机构的对公账户交易记录,且只能在工作时间操作,金额超过 100 万的交易需要风控主管复核。”——你试试用 RBAC 实现这个?角色得建几百个。

ABAC 的思路完全不同。它不依赖于预定义的角色,而是用一组“属性”来描述请求的上下文:

  • 用户属性:部门、岗位、职级、地理位置
  • 资源属性:账户类型、余额、所属分支、创建时间
  • 环境属性:当前时间、网络 IP、设备指纹、风险等级
  • 操作属性:查询、转账、修改、删除

策略引擎根据这些属性实时计算是否允许访问。说白了,ABAC 就是给每个访问请求做一次“条件判断”。

ABAC 的官方定义:基于属性的访问控制(Attribute-Based Access Control),是一种根据主体、资源、环境和操作等属性的组合,通过策略规则动态判定访问权限的模型。它由 NIST 在 SP 800-162 中标准化。

核心概念:属性、策略、策略引擎

嗯,这里要注意:ABAC 不是几个属性堆在一起就完事了。它需要三个核心组件协同工作。

1. 属性(Attribute)

属性是 ABAC 的最小单元。我个人习惯把属性分为四类:

属性类型示例来源
主体属性userId, role, department, clearanceLevelIDP、HR系统
资源属性resourceType, owner, sensitivity, region资源目录、数据库
环境属性currentTime, ipRange, deviceTrustScore上下文服务、监测
操作属性action, method, apiVersion请求本身

2. 策略(Policy)

策略就是 if-then 规则。我写过最长的策略有 47 个条件,但现实中 3~5 个条件就够用了。举个例子:

# 典型的 ABAC 策略(XACML 风格)
Rule "主管审批超过100万的交易"
  Target subject.role == "风控主管"
  Condition
    resource.accountType == "对公" AND
    resource.amount > 1000000 AND
    environment.currentTime BETWEEN "09:00" AND "18:00"
  Effect: Permit

3. 策略引擎(Policy Engine / PEP-PDP)

策略引擎负责接收请求,收集属性,匹配策略,最后返回 Permit/Deny。架构上通常分为:

  • PEP(策略执行点):拦截请求,向 PDP 发起决策咨询。
  • PDP(策略决策点):加载策略规则,执行属性匹配,做出决策。
  • PIP(策略信息点):提供属性值,可能调用 API 或数据库。
  • PAP(策略管理点):供管理员编写和管理策略。

下图展示了这些组件的关系:

ABAC 核心组件与数据流 请求者 PEP PDP PIP PAP 资源 / 数据 注意:PDP 是决策核心,PIP 负责从 LDAP、数据库等源头拉取属性值。PAP 通常是一个管理后台。 实际部署时,PEP 一般嵌入在网关或 SDK 中,PDP 独立为微服务。

我的经验:第一次落地 ABAC 时,我把所有属性都塞进请求头,结果策略引擎解码都要 200ms。后来把常用属性缓存到 PIP 本地,决策时间降到 3ms 以下。记着:属性收集是性能瓶颈,能用缓存就别实时查询。

与 RBAC、DAC 的对比

你想想看,RBAC 为什么在某些场景下会失效?

  • DAC(自主访问控制):资源所有者自己决定谁可以访问。比如 Linux 文件权限,owner 能 chmod。优势是灵活,劣势是管理失控——用户可能把敏感文件直接公开。
  • RBAC(基于角色的访问控制):通过角色关联权限,比如“财务经理”角色可以查看所有财报。优势是管理简单,劣势是角色爆炸——当需要“查看本部门且金额在 100 万以下”这种细粒度时,你不得不建子角色。
  • ABAC:没有角色,但可以用属性动态组合出任意粒度的策略。你甚至可以这样写:“允许上班时间从公司 IP 访问,且资源机密等级不超过自己的安全级别”——全凭属性。
维度DACRBACABAC
授权主体资源所有者角色属性
粒度粗(文件级别)中(角色相关)细(任意维度)
动态性静态静态(角色变化慢)动态(实时计算)
管理复杂度高(分散)中(集中管理)中高(需设计属性模型)
典型场景文件系统、个人网盘企业应用、SaaS微服务、金融、医疗
审计追踪难(权限分散)容易非常详细(可回溯属性值)

避坑指南:我曾经在一个项目中试图用 ABAC 完全替代 RBAC,结果策略规则涨到了 8000 多条,PDP 每次启动加载都要 5 分钟。后来我采用混合模式:粗粒度用 RBAC 角色过滤,细粒度再用 ABAC。千万别迷信“全 ABAC”,混合才是王道。

什么时候该选 ABAC?

我给你列几个判断信号:

  1. 权限规则经常变化,且涉及多个维度的组合条件。
  2. 需求中频繁出现“如果…则…否则…”的逻辑,比如“如果是合规部门成员且文档包含 PII,则禁止下载”。
  3. 你无法预定义所有可能的角色,权限需要根据上下文动态生成。
  4. 审计要求记录每次决策的依据(比如“因为用户安全等级是 3,资源机密等级是 2,所以允许访问”)。

如果你发现以上任意一条成立,ABAC 就值得考虑。当然,如果权限只是简单的“管理员可以删、编辑可以改、查看者可以看”,RBAC 完全够用,别给自己找麻烦。

一句话总结:ABAC 用属性代替角色,用策略代替预分配,用引擎代替硬编码。它更灵活,但需要更精心的设计。后面我们会一步步拆解如何设计属性模型和策略语言。