You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Casbin多策略RBAC与ABAC共存时enforce调用报错及规则匹配问题

Casbin多策略RBAC+ABAC配置执行问题解决

问题重现

使用Casbin官方多策略示例配置RBAC与ABAC混合权限控制,模型与策略文件如下:

模型文件 multiple_policy_definitions_model.conf

[request_definition]
r = sub, obj, act
r2 = sub, obj, act

[policy_definition]
p = sub, obj, act
p2= sub_rule, obj, act, eft

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
#RBAC
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
#ABAC
m2 = eval(p2.sub_rule) && r2.obj == p2.obj && r2.act == p2.act

策略文件 multiple_policy_definitions_policy.csv

p, data2_admin, data2, read
p2, r2.sub.Age > 18 && r2.sub.Age < 60, /data1, read, allow
p2, r2.sub.Age > 60 && r2.sub.Age < 100, /data1, read, deny

g, alice, data2_admin

执行以下代码时触发报错:

const { query } = request; // query = {Age:20}
const result = await e.enforce(query, '/data1', 'read');
console.log(result);

报错信息:

TypeError: Cannot convert object to primitive value
    at Array.join (<anonymous>)
    at Array.toString (<anonymous>)
    at D:\mandy\Project\e_shopping_api\node_modules\casbin\lib\cjs\util\builtinOperators.js:286:26
    at D:\mandy\Project\e_shopping_api\node_modules\expression-eval\dist\expression-eval.js:1:519
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.generatorRunAsync (D:\mandy\Project\e_shopping_api\node_modules\casbin\lib\cjs\util\util.js:160:26)
    at async Object.handler (D:\mandy\Project\e_shopping_api\src\routes\root.js:81:20)

问题原因

  1. 默认匹配器不匹配:enforce()方法默认使用模型中定义的r请求规则和m匹配器,而m中包含RBAC的角色匹配逻辑g(r.sub, p.sub),但传入的sub是对象{Age:20},g函数需要字符串类型的角色标识,导致对象转字符串时抛出类型错误。
  2. 策略生效范围不足:原模型的policy_effect仅判断p策略的allow,未包含p2策略的生效逻辑,即使触发m2匹配也无法正确返回权限结果。

解决方案

1. 调整模型的策略生效规则

修改[policy_effect]部分,让它同时考虑p和p2的权限结果:

[policy_effect]
e = some(where (p.eft == allow || p2.eft == allow))

2. 明确指定使用ABAC匹配器

使用Casbin的enforceExplicitWithMatcher()方法,显式指定使用m2匹配器,对应r2请求规则:

const { query } = request;
// 显式指定使用m2匹配器执行ABAC规则校验
const result = await e.enforceExplicitWithMatcher("m2", query, '/data1', 'read');
console.log(result); // 应返回true

补充:混合RBAC与ABAC的通用匹配器

如果需要同时支持RBAC(字符串sub)和ABAC(对象sub)的请求,可以合并匹配器逻辑,避免每次指定匹配器:

[matchers]
m = (g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act) || (eval(p2.sub_rule) && r.obj == p2.obj && r.act == p2.act)

此时直接使用enforce()即可自动适配两种场景:

  • 当sub为字符串(如alice)时,走RBAC规则;
  • 当sub为对象(如{Age:20})时,走ABAC规则。

验证

调整后,传入{Age:20}请求/data1的read权限,会触发p2的r2.sub.Age >18 && <60规则,返回true;若传入{Age:70},则触发deny规则,返回false。

内容的提问来源于stack exchange,提问作者Chen Mandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 19:01:28