2. 属性基础
好,咱们直接切入正题。
ABAC 的核心就仨字——看属性。说白了,就是拿一堆属性做加减乘除,最后决定你能不能进门。我见过不少团队,策略写得花里胡哨,结果卡在属性定义上。属性没理清,后面全白搭。
主体属性:你是谁,以及你凭什么
主体属性描述的是谁在发起访问请求。这可不是简单一个用户 ID 就完事的。我在项目中见过最典型的问题,就是只用了角色,然后发现角色根本不够用。
常用的主体属性可以分成这几类:
- 身份类:用户 ID、用户名、员工编号、邮箱地址。这些是静态的,基本不变。
- 组织类:部门、团队、项目组、汇报线、岗位层级。这些往往决定了你的工作范围。
- 资质类:权限等级、安全秘级、技能认证、项目角色。比如,只有持有“PCI-DSS 审计员”认证的人,才能查看支付流水。
- 行为类:登录时间、IP 地址、设备指纹、会话状态、MFA 方式。嗯,这些动态属性,是防攻击的关键。
“有个坑,我踩过好几次。千万别把所有主体属性硬编码在请求里。我习惯把身份类、组织类放在身份令牌 JWT 里,资质类和行为类由策略决策点(PDP)实时去身份管理平台或监控系统取。这样一旦员工调岗,属性自动更新,策略不用改一行代码。”
客体属性:你要动什么,它有多敏感
客体属性针对的是被访问的资源。你想想看,同样一个“读取”动作,读一篇公开博客和读一份员工薪资单,能一样吗?
客体属性通常包括:
- 标识类:资源 ID、资源名称、资源类型(API / 文件 / 数据库记录)。
- 秘级类:数据分类(公开 / 内部 / 机密 / 绝密)、监管合规标签(GDPR / HIPAA / PCI)。
- 元数据类:创建者、创建时间、最后修改时间、所有者部门、版本号。
- 状态类:是否归档、是否已删除、是否处于审批流程中。我曾在项目中遇到一个事故,就是因为没判断“文档是否已锁定”,结果两个人同时编辑导致内容冲突。
这里有一个区分技巧,我个人觉得特别实用:
| 属性类别 | 静态客体属性 | 动态客体属性 |
|---|---|---|
| 定义 | 资源创建后基本不变 | 随资源生命周期不断变化 |
| 举例 | 资源类型、创建者、数据秘级 | 当前状态、最后访问时间、当前所有者 |
| 典型用途 | 做粗粒度过滤(如“所有绝密文件禁止公开下载”) | 做细粒度检查(如“只允许文档所有者修改”) |
| 获取方式 | 直接读资源元数据表 | 调用资源管理服务实时查询 |
“我遇到过一件非常头疼的事。有次一个第三方服务通过 API 批量拉取订单数据,它的客体是‘订单ID范围’。结果我们只检查了单个订单的秘级,没检查这个‘订单集合’的敏感度。对方用一串低敏订单 ID 拼出了一个完整的高敏客户画像。教训是:处理好客体集合的属性,尤其是当请求涉及多个资源时,策略要把集合视为一个整体来评估。”
环境属性:你在什么时间、什么地方、用什么设备来操作
环境属性单独划出来,是因为它既不依赖用户,也不依赖资源,它描述的是访问发生的上下文。
- 时间类:当前时间、业务时间、时区。比如,只允许工作日上午 9 点到下午 6 点发起批量数据导出。
- 位置类:IP 地理位置、办公地点、连接的 Wi-Fi SSID、国家/地区。
- 设备类:设备型号、操作系统版本、是否越狱、是否安装合规客户端。
- 风险类:当前网络威胁等级、用户行为的异常评分、登录频率。
- 运行环境类:内部网络还是外部网络、是否通过 VPN、是否处于灾备模式。
“我建议环境属性一定要放在策略的最前面做快速拒绝。比如‘如果当前网络威胁等级为高,则直接拒绝所有写入操作’。这样可以节省后端大量的计算资源。环境属性往往是策略的第一道防线。”
为什么会这样?因为环境属性变化最快,且不受单个主体或客体控制。把环境检查放在前面,能最大程度减少无效的资源查询和鉴权计算。
好,到这里三种属性就讲完了。我们用一个图把它们串起来,看看在一条 ABAC 策略里,这些属性是怎么流动的:
图里的结构很清楚。主体、客体、环境三类属性汇入 PDP,PDP 根据预设的策略逻辑进行匹配计算,最终输出 Permit 或 Deny。每一次决策都是一次属性的组合运算。
最后,我简单总结一下这三类属性的核心区别,方便你快速回顾:
| 属性类型 | 描述什么 | 示例值 | 变更频率 | 获取来源 |
|---|---|---|---|---|
| 主体属性 | 谁在发请求 | employee_id: 1024, role: engineer | 低(除行为类属性外) | JWT / IDM |
| 客体属性 | 请求访问什么 | resource_type: document, classification: confidential | 中 | 资源元数据服务 |
| 环境属性 | 何时、何地、何种条件 | time: 10:00, network: internal, risk_score: 0.2 | 高 | 运行时基础设施 |
嗯,到这属性基础就讲完了。记住这三类属性的区分,后面设计策略的时候才能游刃有余。