CASL ABAC是否支持Bigint解析?权限校验失败排查
CASL ABAC权限校验失败原因及解决办法
问题描述
使用CASL ABAC进行权限校验时,传入的subject对象为permissions.can("read", subject("appprofile", profile)),待校验的profile结构为:
{ name: "Dave", id: 1n, // 来自Prisma的bigint }
createMongoAbility使用的JSON规则为:
[ { "action": "read", "subject": "appprofile", "conditions": { "id": "1" } } ]
但校验失败,是否是CASL的Bigint解析问题?
原因分析
是类型不匹配导致的校验失败,核心问题在于:
- profile中的
id是BigInt类型(1n) - 规则条件中的
id是字符串类型("1")
CASL执行MongoDB风格的条件匹配时,会做严格的类型相等校验,不同类型的值即便字面量一致也会判定为不匹配。另外JSON本身不支持BigInt类型,无法直接在JSON规则中定义BigInt值,这也间接加剧了类型差异问题。
解决办法
可以通过以下几种方式处理:
- 转换规则中的条件值类型:加载JSON规则后,将条件里的字符串id转为BigInt:
const rules = require('./rules.json').map(rule => { if (rule.subject === 'appprofile' && rule.conditions?.id) { rule.conditions.id = BigInt(rule.conditions.id); } return rule; }); const ability = createMongoAbility(rules); - 转换subject对象的id类型:传入CASL校验前,把profile的BigInt id转成字符串:
const profileToCheck = { ...profile, id: profile.id.toString() }; permissions.can("read", subject("appprofile", profileToCheck)); - 自定义CASL匹配逻辑:扩展MongoAbility的匹配器,让BigInt与字符串可兼容判断,比如重写
eq操作符:import { createMongoAbility, MongoQuery } from '@casl/ability'; class CustomMongoQuery extends MongoQuery { eq(a: any, b: any) { if (typeof a === 'bigint' && typeof b === 'string') { return a.toString() === b; } if (typeof b === 'bigint' && typeof a === 'string') { return b.toString() === a; } return super.eq(a, b); } } const ability = createMongoAbility(rules, { query: CustomMongoQuery });
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

