属性基础:主体、客体、环境属性详解

好,咱们直接切入正题。

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 策略里,这些属性是怎么流动的:

ABAC 属性构成与评估流程 主体属性 用户ID / 角色 / 部门 客体属性 资源秘级 / 类型 / 所有者 环境属性 时间 / 位置 / 风险等级 策略决策点 (PDP) 计算策略逻辑 允许 (Permit) 禁止 (Deny) 💡 属性存储说明 • 主体属性:多存放在身份管理系统(IDM)或 JWT 令牌中 • 客体属性:存放在资源元数据服务(如 CMDB、标签引擎)中 • 环境属性:由安全监控、网络、设备管理等基础设施实时提供

图里的结构很清楚。主体、客体、环境三类属性汇入 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高运行时基础设施

嗯,到这属性基础就讲完了。记住这三类属性的区分,后面设计策略的时候才能游刃有余。