Casbin配置文件详解,结合RBAC模型设计权限、角色、用户业务逻辑

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act, eff

[role_definition]
g = _, _

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

[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act

[request_definition]用来定义一次请求的参数结构,也就是完成一次鉴权需要哪些字段
举例:"roleId", "/data/resource", "GET"
[policy_definition]用来定义“策略(Policy)表”这一行数据的数据结构
举例:p, roleName, /data/resource, GET, allow
[role_definition]用来定义“角色(RBAC)”关系,第一个参数是“成员”,第二个参数是“角色”
举例:g, alice, dev , g, alice, ops,用户与角色是多对多的关系。
[policy_effect]用来定义权限拒绝策略,
e = some(where (p.eft == allow)) && !some(where (p.eft == deny)),意思是只要有一条 deny 命中,就拒绝;只有在“有任意一条 allow 且没有 deny”的情况下,才允许放行。
[matchers]用来定义策略匹配逻辑,m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act,意思是一条请求是否被允许,请求中的用户 r.sub,拥有策略中定义的角色 p.sub,keyMatch2匹配url的带参数路径,请求的操作必须和策略中定义的操作完全一致,才允许放行。

r :request 的缩写,代表一次访问请求
p :policy 的缩写,代表一行权限策略
g :group 的缩写,代表权限分组
m :matcher 的缩写,代表如何匹配权限策略

字段 含义 说明
sub subject 访问主体(用户 / 角色 / 客户端 ID 等)
obj object 访问对象(资源、URL、API、文件路径等)
act action 操作行为(GET / POST / PUT / DELETE 等)
eff effect 策略生效结果(通常是 allow 或 deny)

全量删插(本地内存与持久化同步)

Casbin 的 Enforcer 在内存里维护了一份策略镜像,同时靠 Adapter(如数据库)持久化存储。

  • :调用类似清除全量策略的接口时,会先清内存,再通过 Adapter 删掉存储介质(DB/文件)里的所有规则
  • :随后批量写入新策略,会同时写进内存模型与底层存储,保证两者一致。
  • 关键点:这一步默认只发生在当前这个 Enforcer 实例上,别的节点完全感知不到,它们的内存里还是旧策略。

Watcher(多节点广播通知)

在分布式/多实例部署时,A 节点全量删插了,B、C 节点并不知道,会继续用旧策略鉴权,导致结果不一致。Watcher 就是用来解决这个问题的“消息喇叭”:

  • 原理:基于发布订阅(如 Redis Pub/Sub、etcd、Kafka 等)。当前节点执行 SavePolicy()等变更操作时,Casbin 会自动调用 Watcher.Update()往消息通道发一条信号(“策略变了!”)。
  • 接收方动作:其他节点的 Watcher 收到信号后,触发预设的回调函数,通常就是执行 LoadPolicy()从 DB 重新全量拉取策略覆盖本地内存,从而达到集群最终一致。

缓存清理(CachedEnforcer 的命中失效)

如果用的是 CachedEnforcer,它会把 (sub, obj, act)的鉴权结果缓存起来,避免每次都遍历规则,提升性能。

  • 问题:全量删插后,旧缓存全部失效了,如果没清缓存,鉴权还会命中错误的旧结果。

  • 机制

    • 自动清理:通过当前实例正常增删改策略(如 AddPolicy)时,CachedEnforcer 会自动失效相关缓存条目
    • 手动清理:全量操作或收到 Watcher 通知重新 LoadPolicy()时,通常需要显式调用 InvalidateCache()清空全部缓存,或依赖重新加载时内部清空,确保下次鉴权重新计算并从最新策略里匹配。

三者串联的完整链路

管理员在节点 A​ 执行全量删插 → A 的内存与 DB 更新 → A 的 Watcher 发通知 → 节点 B/C​ 收到信号 → 各自触发回调执行 LoadPolicy()从 DB 重载内存 → 各自执行缓存清理失效旧结果 → 后续所有鉴权基于最新策略重新计算,达成一致性。

引用官方资料:https://casbin.apache.org/zh/docs/function

keyMatch /alice_data/resource1这样的URL路径 /alice_data/*这样的URL路径或*模式 keymatch_model.conf/keymatch_policy.csv
keyMatch2 /alice_data/resource1这样的URL路径 /alice_data/:resource这样的URL路径或:模式 keymatch2_model.conf/keymatch2_policy.csv
keyMatch3 /alice_data/resource1这样的URL路径 /alice_data/{resource}这样的URL路径或{}模式 https://github.com/casbin/casbin/blob/277c1a2b85698272f764d71a94d2595a8d425915/util/builtin_operators_test.go#L171-L196
keyMatch4 /alice_data/123/book/123这样的URL路径 /alice_data/{id}/book/{id}这样的URL路径或{}模式 https://github.com/casbin/casbin/blob/277c1a2b85698272f764d71a94d2595a8d425915/util/builtin_operators_test.go#L208-L222
keyMatch5 /alice_data/123/?status=1这样的URL路径 /alice_data/{id}/*这样的URL路径,{}*模式 https://github.com/casbin/casbin/blob/1cde2646d10ad1190c0d784c3a1c0e1ace1b5bc9/util/builtin_operators_test.go#L485-L526
regexMatch 任何字符串 一个正则表达式模式 keymatch_model.conf/keymatch_policy.csv
ipMatch 192.168.2.123这样的IP地址 192.168.2.0/24这样的IP地址或CIDR ipmatch_model.conf/ipmatch_policy.csv
globMatch /alice_data/resource1这样的路径样式路径 /alice_data/*这样的glob模式 https://github.com/casbin/casbin/blob/277c1a2b85698272f764d71a94d2595a8d425915/util/builtin_operators_test.go#L426-L466
keyGet /proj/resource1这样的URL路径 /proj/*这样的URL路径或*模式 \
keyGet2 /proj/resource1这样的URL路径 a URL path or : pattern like /proj/:resource 在模式中指定的键名
keyGet3 /proj/res3_admin/这样的URL路径 /proj/{resource}_admin/*这样的URL路径或{}模式 在模式中指定的键名
posted @ 2026-07-14 16:32  leoture  阅读(7)  评论(0)    收藏  举报