ABAC模型中如何实现集合内被拒绝访问条目的过滤
ABAC 场景下列表查询自动排除 Deny 条目实现方案
核心实现思路
ABAC 遵循Denay 优先的决策规则,要实现全量查询时自动过滤被拒条目,不需要修改权限模型本身,只要把权限规则和数据查询逻辑打通即可,常用两种落地方案:
1. 前置查询条件拼接方案(性能最优,推荐大部分场景使用)
- 核心逻辑:把 ABAC 的 Deny 规则直接转化为数据查询的过滤条件,在数据库查询阶段就把被拒条目排除,不需要查出来再做二次处理
- 实现步骤:
- 调用权限模块接口,拉取当前用户
U针对CollectionX的所有显式 Deny 规则,提取被拒条目的匹配规则:如果是固定 ID 级别的 Deny 就提取 ID 列表,如果是属性级 Deny 就提取属性匹配条件 - 把 Deny 规则转化为查询语句的排除条件:比如 SQL 中新增
AND id NOT IN (/* 被拒条目 ID 列表 */),MongoDB 中新增{ _id: { $nin: [/* 被拒条目 ID 列表 */] } },属性级规则直接拼接对应属性的排除条件即可 - 拼接后的查询语句执行后得到的结果就是自动排除 Deny 条目的全量列表
- 调用权限模块接口,拉取当前用户
- 优势:对业务侵入低,性能和普通查询几乎无差异,适合大数据量查询场景
2. 后置结果过滤方案(适合规则复杂无法直接转查询条件的场景)
- 核心逻辑:先查询到符合业务条件的全量条目,再逐条调用 ABAC 决策引擎判断权限,过滤掉决策结果为 Deny 的条目后返回
- 实现步骤:
- 业务层先执行原始的
CollectionX全量查询,拿到原始条目列表 - 遍历每个条目,将三类属性传入 ABAC 决策引擎:用户属性(用户ID、所属用户组、标签等)、资源属性(条目ID、所属集合、自定义属性等)、操作属性(操作类型为列表查询)
- 仅保留决策结果为
Allow的条目,最终返回给用户
- 业务层先执行原始的
- 注意:该方案性能会随条目数量增长下降,仅适合小数据量场景,或者搭配分页查询使用,每次仅过滤当前页的条目即可
微服务架构适配优化
- 如果权限服务是独立微服务,可以把规则转查询条件的逻辑封装到权限服务 SDK 中,业务服务查询列表前直接调用 SDK 获取对应集合的过滤条件,不需要重复实现规则解析逻辑
- 如果使用
OPA作为 ABAC 决策引擎,可以直接用 OPA 的 Partial Evaluation 特性直接生成结构化的查询过滤条件,减少自定义规则解析的开发量
内容的提问来源于stack exchange,提问作者snakeduse
相关产品推荐
相关产品推荐

