3 ABAC策略语言基础:XACML简介、策略集合、规则、目标与条件
做ABAC落地,绕不开策略语言。市面上可选的有XACML、ALFA、甚至自己写DSL。但我个人习惯——只要不是极端边缘场景,先看XACML。为什么?因为它的结构已经被全球几百个生产系统验证过,坑都踩平了。
说白了,XACML就是一套用来描述“谁在什么条件下能对什么资源做什么”的标准XML方言。你不需要背完整个规范,但核心概念必须吃透:策略集合、策略、规则、目标、条件。这五个东西组成了XACML的骨骼。
3.1 从业务需求到策略结构
先看一个真实业务规则:
- 只有“高级工程师”或“项目经理”角色的人,才能在“工作时间内”查看“项目成本”报表。
这个需求在XACML里怎么拆?
- 谁 → 请求的主体属性(角色)
- 什么资源 → 资源属性(报表类型)
- 什么操作 → 动作属性(查看)
- 什么条件 → 环境属性(工作时间)
XACML 用 目标(Target) 来匹配前三个,用 条件(Condition) 来处理第四个。目标只做简单的等值或模式匹配,条件支持更复杂布尔逻辑。
3.2 五层体系一次理清
先看整体结构的SVG图,方便建立全局印象。
从上图可以看出一个大原则:策略集合(PolicySet) 包含策略(Policy),策略包含规则(Rule)。每个节点都可能有自己的目标,但规则的目标通常继承自父容器。
3.3 各组件详解
3.3.1 PolicySet(策略集合)
用于分组管理策略。典型用途是按域、应用或环境切分。比如“生产环境策略集合”、“开发环境策略集合”。
属性:
PolicyCombiningAlg:策略组合算法,决定多个策略冲突时谁说了算(如:先适用、拒绝优先、允许优先)Target:可选,若指定,只处理匹配该目标的请求
3.3.2 Policy(策略)
策略是策略集合的子节点,它才是真正的决策单元。一个Policy包含一个或多个Rule,以及自己的RuleCombiningAlg。
对比一下:
| 组件 | 组合算法作用范围 | 典型场景 |
|---|---|---|
| PolicySet | 多个Policy之间 | 按环境拆分(prod/test) |
| Policy | 内部多个Rule之间 | 一个资源的多条权限规则 |
3.3.3 Rule(规则)
Rule是真正的原子决策单元。每个Rule有:
- Effect:Permit 或 Deny
- Target:可选(通常继承Policy的Target再细化)
- Condition:布尔表达式,返回True才生效
- Obligation / Advice:附加指令(如审计日志),不是本章重点
看一个具体例子:
<Rule RuleId="成本报表-工作时间规则" Effect="Permit">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="string-equal">
<AttributeValue DataType="string">高级工程师</AttributeValue>
<AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
AttributeId="role"/>
</Match>
</AllOf>
</AnyOf>
<!-- 项目经理角色同样匹配 -->
</Target>
<Condition>
<Apply FunctionId="time-in-range">
<Apply FunctionId="time-one-and-only">
<AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:environment-category:environment"
AttributeId="current-time"/>
</Apply>
<AttributeValue DataType="time">09:00:00</AttributeValue>
<AttributeValue DataType="time">18:00:00</AttributeValue>
</Apply>
</Condition>
</Rule>
这段代码核心就是:如果请求者角色是“高级工程师”或“项目经理”,并且当前时间在09:00~18:00之间,则允许访问。注意Condition里用了一个自定义函数 time-in-range,XACML允许扩展自有函数。
3.3.4 Target(目标)
Target的作用很明确:快速过滤。它只做简单匹配(等于、不等于、子集等),不做复杂计算。PDP在处理请求时,先用Target找到匹配的策略和规则,跳过不相关的分支,性能全靠它。
Target的四个维度:
- Subject:主体(谁)
- Resource:资源(什么)
- Action:动作(操作)
- Environment:环境(可选,比如当前时间、位置)
在实际项目中,我建议把80%的过滤逻辑放在Target层。Condition只用来兜底。这样做的好处是——PDP可以快速拒绝无关请求,Condition的布尔计算次数降到最低。
3.3.5 Condition(条件)
Condition是一个可选的布尔表达式,结果为True则规则生效,False则规则不适用(NotApplicable)。支持嵌套、函数调用、比较。
常用内置函数举例:
string-equal,string-at-least-one-member-ofinteger-greater-than,double-less-thantime-in-range(需自定义或扩展)and,or,not
3.4 组合算法怎么选
当多个规则或策略同时匹配时,谁来定最终结果?这就是组合算法的职责。
常见算法表:
| 算法名称 | 含义 | 使用场景 |
|---|---|---|
| deny-overrides | 只要有一个Deny,最终就是Deny | 安全敏感场景,任何拒绝都不能被覆盖 |
| permit-overrides | 只要有一个Permit,最终就是Permit | 资源开放场景,有人允许就行 |
| first-applicable | 按顺序找第一个生效的规则 | 策略有明确优先级时 |
| only-one-applicable | 只允许一个匹配,否则报错 | 严格隔离场景(比如微服务边界) |
我个人习惯:先在全局用deny-overrides保底,针对具体业务再用first-applicable细化。组合算法本身可以嵌套,PolicySet用一套,Policy用另一套。
3.5 小结
XACML的核心结构其实不复杂:PolicySet装Policy,Policy装Rule,每个节点都可能带Target做过滤,Rule里还能加Condition做精细判断。你把这个层次关系刻在脑子里,就已经掌握了XACML的七成。