Casbin 把访问控制规则拆成一份可配置的模型文件,核心是 PERM:Policy、Effect、Request、Matcher。理解这四部分后,读者不仅能看懂最基础的 ACL 写法,也能判断项目里换授权模型时到底是在改什么、规则是怎样被匹配命中的。本文就从一个最小示例出发,顺着 model、policy 到匹配逻辑逐段拆开,并补充配置换行和 ABAC 条件表达式的使用限制。
PERM 是 Casbin 模型的基础
在 Casbin 中,访问控制模型会被抽象成一份基于 PERM (Policy, Effect, Request, Matcher) 的文件。这样做的直接好处是,项目要切换或升级授权机制时,很多时候不需要重写整套逻辑,而是像修改配置一样调整模型定义。
Casbin 也允许把不同思路的授权方式组合起来使用。比如,你可以在同一个 model 里同时引入 RBAC 的角色关系和 ABAC 的属性判断,并让它们共享同一组 policy 规则。
最小 ACL Model 长什么样
Casbin 里最基本、也最容易上手的 model 是 ACL。它的 Model 配置如下:

# Request definition
[request_definition]
r = sub, obj, act
# Policy definition
[policy_definition]
p = sub, obj, act
# Policy effect
[policy_effect]
e = some(where (p.eft == allow))
# Matchers
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
这份配置可以直接拆成四个部分来看:
Request:一次访问请求包含什么
r = sub, obj, act 表示系统在做授权判断时,会拿出三个要素参与匹配:访问主体 sub、访问对象 obj 和操作动作 act。

Policy:规则表里保存什么
p = sub, obj, act 说明 policy 规则也按同样的三列存储。这样请求中的字段就能和规则中的字段一一对上。

Effect:命中规则后如何生效
e = some(where (p.eft == allow)) 的含义是:只要存在一条规则的效果是 allow,这次请求就可以通过。这也是最常见的“命中即放行”写法。
Matchers:请求与规则如何比对
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act 表示只有当主体、对象、动作三项全部相等时,这条 policy 才算匹配成功。也就是说,这是一个标准的精确匹配 ACL 模型。
示例 Policy 如何对应实际权限
对应这份 ACL Model,示例 Policy 可以写成:
p, alice, data1, read
p, bob, data2, write
它表示两条最直接的授权关系:
alice对data1有read权限bob对data2有write权限
如果把它代回前面的 matcher,就很容易理解 Casbin 的判断过程。比如请求是“alice 读取 data1”,那么 sub、obj、act 三项都能和第一条 policy 对上,请求通过;如果动作或对象不同,就不会命中这条规则。
长表达式换行与 ABAC 条件的注意点
当 matcher 配置过长,Casbin 也支持在一行结尾后继续断行书写,以便提升可读性。例如:
# Matchers
[matchers]
m = r.sub == p.sub && r.obj == p.obj
&& r.act == p.act
这种写法适合把较长的条件表达式拆开,尤其是在模型逐渐复杂、需要混合多种判断条件时,比单行堆满逻辑更容易维护。
另外,针对 ABAC,Casbin 的 golang 和 php 版本可以尝试下面这种写法,jCasbin 和 Node-Casbin 尚不支持:
# Matchers
[matchers]
m = r.obj == p.obj && r.act == p.act || r.obj in ('data2', 'data3')
这段表达式的意思是:除了常规地比较对象和动作,还允许通过 in 判断对象是否属于某个集合。它适合处理“某些资源天然归为同一类”的场景。
不过这里有一个明确限制:你必须确保数组长度大于 1,否则会导致异常。也就是说,这种写法不是随手就能替代普通等值判断,使用前需要先确认集合内容本身是有效的。
理解工作原理后能解决什么问题
如果只看 Casbin 配置文件,很多人容易把它当成简单规则表;但从工作原理看,真正起作用的是 PERM 四部分之间的配合。request_definition 决定请求带哪些字段,policy_definition 决定规则长什么样,policy_effect 决定命中后的裁决方式,matchers 则决定两者如何发生关联。
掌握这一点后,再去看 ACL、RBAC 或 ABAC 的模型差异,思路就会清晰很多:它们本质上都是在调整“请求字段、规则字段、匹配条件和生效方式”这几件事。对于入门者来说,先吃透这个最小 ACL 示例,是理解 Casbin 授权机制最直接的一步。













