浅谈 Casbin 的三种策略效果(Policy Effect):deny-overrides、allow-override 与 priority
🧩 什么是 Casbin?
在现代软件系统中,访问控制(Access Control) 是安全体系的基石之一。无论是微服务、API 网关还是多租户应用,系统都必须回答一个关键问题:
“谁(Who)能在什么条件下(When/Where)对什么资源(What)执行什么操作(How)?”
而 Casbin 正是为了解决这一问题而推出的通用访问控制框架。
Casbin 是一个支持多种访问控制模型(Access Control Model)的开源框架,使用 策略(Policy) 和 模型(Model) 的分离设计,使授权逻辑既灵活又易于扩展。其核心思想可以概括为两部分:
-
Model(模型文件 model.conf)
定义访问控制的抽象逻辑,比如:谁在什么条件下能访问什么资源。[request_definition] r = sub, obj, act # 访问请求:主体、对象、动作[policy_definition] p = sub, obj, act, eft # 策略定义,含效果(Effect)[matchers] m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
-
Policy(策略文件 policy.csv)
定义具体的访问规则:p, alice, data1, read, allow p, bob, data1, write, deny
Casbin 在运行时会将请求(r = sub, obj, act
)与策略(p = sub, obj, act, eft
)进行匹配,根据策略的“效果(Effect)”计算出最终的授权结果。
🔐 支持的访问控制模型
Casbin 不仅支持最常见的 ACL(访问控制列表),还支持:
模型 | 全称 | 应用场景 |
---|---|---|
ACL | Access Control List | 简单用户资源权限 |
RBAC | Role-Based Access Control | 按角色授权,企业系统常用 |
ABAC | Attribute-Based Access Control | 按属性和上下文判断,云平台常用 |
RESTful 模式 | Resource + Method + Path | Web API 权限控制 |
⚙️ 为什么选择 Casbin?
特点 | 说明 |
---|---|
✅ 高可扩展性 | 可在不同语言中使用(Go、Python、Java、Node.js 等) |
🔄 实时授权 | 可动态加载/更新策略而无需重启 |
🧩 模型驱动 | 授权逻辑不写死在代码中,通过模型文件配置 |
🔒 灵活的效果控制(Policy Effect) | 可指定多条策略命中时的决策方式(如 allow 优先 / deny 优先) |
简而言之,Casbin 就像是系统中的“安全守门员”:
当一个请求到来时,它会根据配置的模型(Model)和策略(Policy),用明确定义的逻辑判断“是否允许访问”。
接下来,我们就从 Casbin 的 Policy Effect(策略决策效果) 入手,分析其如何在多条策略命中时做出决策。
Casbin 的三种常用 effect 分别为:deny-overrides
、allow-override
、priority(p.eft)
。
🔹 一、deny-overrides
—— 拒绝优先
规则:只要有一条策略是
deny
,无论其他有多少allow
,都拒绝。
1️⃣ 模型定义(model.conf
)
[request_definition]
r = sub, obj, act[policy_definition]
p = sub, obj, act, eft[policy_effect]
e = !some(where (p.eft == deny)) # 拒绝优先[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
2️⃣ 策略定义(policy.csv
)
p, alice, data1, read, allow
p, alice, data1, read, deny
3️⃣ 执行结果
请求 | 匹配策略 | 结果 |
---|---|---|
(alice , data1 , read ) | 一条 allow + 一条 deny | ❌ 拒绝 |
(alice , data1 , write ) | 无匹配 | ❌ 拒绝 |
✅ 总结:哪怕某条规则允许,只要出现任何 deny,就立即拒绝。
🔹 二、allow-override
—— 允许优先
规则:只要有一条策略是
allow
,无论是否存在deny
,都放行。
1️⃣ 模型定义(model.conf
)
[policy_effect]
e = some(where (p.eft == allow)) # 允许优先
这其实就是 Casbin 默认配置。
2️⃣ 策略定义(policy.csv
)
p, alice, data1, read, deny
p, alice, data1, read, allow
3️⃣ 执行结果
请求 | 匹配策略 | 结果 |
---|---|---|
(alice , data1 , read ) | 一条 deny + 一条 allow | ✅ 允许 |
(alice , data1 , write ) | 无匹配 | ❌ 拒绝 |
✅ 总结:只要有一条 allow,其他 deny 都被忽略。这在一些系统中适合“白名单为主”的模式。
🔹 三、priority(p.eft)
—— 优先级决策
规则:当多条策略命中时,按策略的优先级字段排序,优先级高的结果生效。
1️⃣ 模型定义(model.conf
)
[policy_definition]
p = sub, obj, act, eft, priority # 新增 priority 字段[policy_effect]
e = priority(p.eft) || deny # 按优先级决策
数字越小优先级越高(Casbin 默认按顺序或数字排序)。
2️⃣ 策略定义(policy.csv
)
p, alice, data1, read, deny, 100
p, alice, data1, read, allow, 10
3️⃣ 执行结果
请求 | 匹配策略 | 结果 |
---|---|---|
(alice , data1 , read ) | allow + deny(优先级 10 < 100) | ✅ 允许 |
(bob , data1 , read)` | 无匹配 | ❌ 拒绝 |
若改为:
p, alice, data1, read, deny, 5
p, alice, data1, read, allow, 10
则:
请求 | 结果 |
---|---|
(alice , data1 , read`) | ❌ 拒绝(deny 优先级更高) |
✅ 总结:谁优先级高(priority 小或在上),谁决定最终结果。非常适合“用户专属规则 > 角色通用规则”这样的层次化授权。
🔸 四、三种 effect 对比总结
下图展示了 Casbin 的三种 effect 模式在多条策略命中时的决策逻辑流程。
Effect 模式 | 配置语句 | 含义 | 结果示例 |
---|---|---|---|
deny-overrides | e = !some(where (p.eft == deny)) | 一旦有 deny,全部拒绝 | allow + deny → ❌ |
allow-override | e = some(where (p.eft == allow)) | 一旦有 allow,就放行 | allow + deny → ✅ |
priority(p.eft) | e = priority(p.eft) | 由优先级字段控制结果 | 按 priority 字段判断 |
🔹 五、实际工程中选择建议
场景 | 推荐 effect | 说明 |
---|---|---|
银行、支付系统 | deny-overrides | 安全优先:有疑必拒 |
SaaS / API 平台 | allow-override | 灵活开放:显式允许即可 |
大型企业多层角色 | priority(p.eft) | 便于覆盖继承:用户特例 > 角色默认 |