4. ABAC 基础理论:核心要素、属性来源与策略评估
基于属性的访问控制(ABAC)通过评估主体、资源、环境和动作的任意属性组合来做出授权决策。与 RBAC 的静态角色不同,ABAC 在运行时动态计算策略,能够表达“仅当用户是项目经理且当前 IP 属于内网且请求时间在 09:00-18:00 之间时,才允许修改合同金额”这类细粒度规则。本节将拆解 ABAC 的四大核心要素、属性定义与来源、策略评估引擎以及策略组合算法。
4.1 ABAC 核心要素
ABAC 模型围绕四个基本要素构建:主体(Subject)、资源(Resource)、环境(Environment)和动作(Action)。每个要素都携带一组属性,策略引擎通过匹配这些属性来决定是否允许访问。
| 要素 | 定义 | 典型属性示例 |
|---|---|---|
| 主体 (S) | 发起访问请求的实体,通常是用户或服务 | user_id, role, department, clearance_level, ip_address |
| 资源 (R) | 被访问的对象,如文件、API、数据库记录 | resource_type, owner, classification, region, project_id |
| 环境 (E) | 访问发生时的上下文,不依赖主体或资源 | current_time, network_zone, device_type, risk_level |
| 动作 (A) | 主体对资源执行的操作 | action_type (read/write/delete), http_method, effect |
关键区别:RBAC 的决策基于“用户是什么角色”,ABAC 的决策基于“用户、资源、环境各自有什么属性”。属性可以来自多个数据源,且可以在运行时动态计算。
4.2 属性定义与属性来源
属性是 ABAC 策略的最小数据单元。每个属性必须有一个明确的名称、数据类型和来源。属性来源通常分为三类:
- 静态来源:用户属性表、资源元数据、配置文件。例如:用户所在部门、资源的创建时间。
- 动态来源:运行时计算或外部系统查询。例如:当前风险评分、用户最近一次登录时间、资源的实时访问量。
- 上下文来源:请求本身携带的信息。例如:请求 IP、User-Agent、请求时间戳。
最佳实践:属性定义应遵循“最小必要原则”——只引入策略中实际使用的属性。每增加一个属性,都会增加策略评估的复杂度和数据同步的维护成本。
| 属性类别 | 示例属性 | 典型来源 | 更新频率 |
|---|---|---|---|
| 主体属性 | department, clearance_level, employment_type | HR 系统 / LDAP / IDP | 低(日/周同步) |
| 资源属性 | classification, owner_team, data_sensitivity | CMDB / 数据目录 / 资源元数据 | 中(事件驱动) |
| 环境属性 | current_time, network_zone, device_risk_score | 运行时上下文 / 安全扫描服务 | 高(每次请求) |
| 动作属性 | http_method, action_scope, is_batch_operation | API 网关 / 请求解析 | 高(每次请求) |
4.3 策略评估引擎
策略评估引擎是 ABAC 的核心运行时组件。它接收访问请求,提取主体、资源、环境和动作的属性,然后根据预定义的策略集进行匹配和评估。评估引擎的工作流程通常包含以下步骤:
- 属性收集:从请求上下文、数据存储和外部服务中收集所有相关属性。
- 策略检索:根据资源类型和动作类型,从策略库中检索适用的策略。
- 条件匹配:将收集到的属性值与策略中的条件表达式进行匹配。
- 决策计算:根据匹配结果和策略组合算法,计算最终决策(Permit / Deny / NotApplicable / Indeterminate)。
- 决策返回:将决策结果返回给 PEP(策略执行点)。
性能陷阱:如果策略引擎在每次请求时都查询外部数据库获取属性,延迟会急剧上升。建议对低频变化的属性(如用户部门、资源分类)使用本地缓存,对高频变化的属性(如风险评分)使用异步更新或预计算。
4.4 策略组合算法
当多个策略同时适用于一个请求时,策略组合算法决定了最终的授权结果。常见的组合算法包括:
- Deny-Overrides(拒绝优先):只要有一条策略结果为 Deny,最终结果即为 Deny。适用于安全敏感场景。
- Permit-Overrides(允许优先):只要有一条策略结果为 Permit,最终结果即为 Permit。适用于需要最大化开放权限的场景。
- First-Applicable(首次匹配):按策略优先级顺序评估,返回第一个匹配的决策。适用于策略有明确优先级层级的情况。
- Only-One-Applicable(唯一适用):如果恰好只有一条策略适用,则返回该策略的决策;如果多条策略适用,则返回 Indeterminate(不确定)。适用于需要避免策略冲突的场景。
| 算法 | 行为 | 适用场景 | 风险 |
|---|---|---|---|
| Deny-Overrides | 任何 Deny 即 Deny | 金融交易、数据删除 | 可能过度拒绝 |
| Permit-Overrides | 任何 Permit 即 Permit | 只读报表、公开 API | 可能过度放行 |
| First-Applicable | 按优先级返回首个匹配 | 分层权限、紧急覆盖 | 策略顺序错误导致绕过 |
| Only-One-Applicable | 仅单策略适用时返回 | 合规审计、严格隔离 | 策略重叠导致 Indeterminate |
工程建议:在混合模型中,通常将 Deny-Overrides 作为全局默认算法,确保安全底线;对于特定资源域(如公开文档),可以降级为 Permit-Overrides。策略组合算法应在策略库的顶层配置中显式声明,避免隐式默认值带来的安全风险。
4.5 策略示例:ABAC 策略的 JSON 表示
以下是一个典型的 ABAC 策略定义,使用 JSON 格式表达。该策略表示:仅当用户属于“finance”部门、资源分类为“confidential”、请求时间在工作时间内、且动作为“read”时,才允许访问。
{
"policyId": "policy-finance-read-confidential",
"description": "允许财务部门在工作时间读取机密财务文档",
"target": {
"resourceType": "financial_document",
"action": "read"
},
"condition": {
"allOf": [
{ "subject.department": { "equals": "finance" } },
{ "resource.classification": { "equals": "confidential" } },
{ "environment.current_time": { "between": ["09:00", "18:00"] } }
]
},
"effect": "Permit",
"priority": 100,
"combineAlgorithm": "Deny-Overrides"
}
属性路径约定:上述示例中的
subject.department、resource.classification、environment.current_time 是属性路径的常见命名方式。建议在团队内统一属性命名规范,避免因大小写或分隔符不一致导致策略失效。