Authorization - Casbin Plugin
Overview
Casbin 的核心只负责策略执行逻辑(model + policy),而插件负责连接外部世界 - 数据库、消息队列、Web 框架等
| 类别 | 中文名 | 作用 |
|---|---|---|
| Enforcers | 专用执行器 | 针对特定环境或场景定制的执行器 |
| Adapters | 存储适配器 | 对接数据库/文件/云存储,读写 model 和 policy |
| Watchers | 变更监听器 | 多实例之间同步 policy 变更 |
| Dispatchers | 分发协调器 | 分布式部署下协调策略更新 |
| Role Managers | 角色管理器 | 自定义角色继承/层级逻辑 |
| Middlewares | 框架中间件 | 集成 Gin、Nest.js、GraphQL、Kong 等 |
Adapters(最常用)
- 解决”policy 存哪“的问题
- 支持 MySQL、PostgreSQL、Redis、MongoDB、文件等
- Casbin 核心本身只内置了文件 Adapter
Watchers(分布式关键)
- 解决”多个 Casbin 实例间 policy 如何保持一致“的问题
- 典型实现:Redis Pub/Sub、Etcd
- 一个实例更新 policy → watcher 广播 → 其他实例重载
Dispatchers(更强一致性)
- 比 Watcher 更进一步,协调分布式下的写操作
- 适用于需要强一致性的场景
Role Managers
- 解决”角色继承逻辑如何定制“的问题
- 默认内置一个内存 role manager,插件可替换为图数据库等
使用流程
选择插件类别 → 安装对应包 → 创建 Enforcer 时注入 → 按插件文档配置高级选项
Enforcers
Casbin 提供了多种 Enforcer 变体,满足不同部署场景的需求
| Enforcer | 核心特性 | 适用场景 |
|---|---|---|
| Enforcer | 基础实现,核心 API | 单节点、简单场景 |
| CachedEnforcer | 内存缓存鉴权结果,可配置过期时间,读写锁线程安全 | 高频鉴权、性能敏感 |
| SyncedEnforcer | 全 API 加同步锁 | 多线程并发写 |
| SyncedCachedEnforcer | 缓存 + 同步锁,两者结合 | 多线程 + 高频鉴权 |
| DistributedEnforcer | 包装 SyncedEnforcer,配合 Dispatcher 工作 | 多节点分布式部署 |
| ContextEnforcer | 支持 Context 参数的 Adapter 操作 | 需要超时/取消控制的场景 |
关键区别
| 系列 | 描述 |
|---|---|
| Cached 系列 | 缓存的是鉴权结果(Enforce() 的返回值),减少重复计算开销 |
| Synced 系列 | 对所有操作加锁,保证并发安全 |
| Distributed | 依赖 Dispatcher 实现跨节点策略广播,是真正的分布式方案 |
| Context | 为 Adapter 操作注入 context.Context,便于与链路追踪、超时控制集成 |
Adapters
Casbin Adapter 是策略持久化的核心扩展点
核心概念
Adapter 的职责:Enforcer 通过 Adapter 调用 LoadPolicy() 加载规则、SavePolicy() 持久化规则,Adapter 把 Casbin 与具体存储解耦
Adapter 分类
| 类型 | 代表 | 说明 |
|---|---|---|
| File | 内置 File Adapter | CSV 文件,最简单,不支持 AutoSave |
| SQL | SQL Adapter, Filtered PostgreSQL | 直接用 database/sql |
| ORM | GORM/Xorm/Ent/Beego | 主流 ORM 封装,大多支持 AutoSave |
| NoSQL | MongoDB/RethinkDB/Cassandra/DynamoDB | 文档/列式数据库 |
| KV store | Redis/Etcd/BoltDB/BadgerDB | 键值存储 |
| Cloud | S3/Firestore/DynamoDB/CosmosDB | 云原生存储 |
| String/Stream | JSON/Protobuf/String | 内存/序列化场景 |
四个接口层次
1 | Adapter(必须) |
1 | Auto-Save(可选,单条增量操作) |
1 | UpdateAdapter(可选,更新操作) |
1 | ContextAdapter(可选,注入 context) |
AutoSave vs SavePolicy()
| 维度 | SavePolicy() | AutoSave |
|---|---|---|
| 操作方式 | 清空全表 + 全量重写 | 单条增量写 |
| 性能 | 策略量大时慢 | 高效 |
| 原子性 | 全量替换 | 单条操作 |
| 适用场景 | 策略迁移、初始化 | 日常增删改 |
通过 e.EnableAutoSave(false) 可关闭 AutoSave,此时 AddPolicy() 等 API 只更新内存,需手动调用 SavePolicy() 落盘
策略迁移方法
1 | e.SetAdapter(A); e.LoadPolicy() // 从 A 加载 |
自定义 Adapter 要点
- 表名默认 casbin_rule,字段 ptype, v0~v5,唯一索引建在 (ptype,v0,v1,v2,v3,v4,v5)
- 不支持 AutoSave 时,三个可选方法返回 errors.New(“not implemented”),Casbin 会自动忽略该错误
- 约定:Adapter 应自动创建 casbin 数据库(如不存在)
- 事务支持:实现 TransactionalAdapter 接口,配合 casbin.NewTransactionalEnforcer 使用
Watchers
Watcher 的职责:在多节点部署中保持策略同步。某个 Enforcer 实例更新策略后,通过消息总线通知其他实例重载策略,避免负载均衡后各节点策略不一致
两种接口
Watcher vs WatcherEx 对比 - 注:WatcherEx 目前没有官方实现,官方推荐用 Dispatcher 实现增量同步
| 维度 | Watcher | WatcherEx |
|---|---|---|
| 通知粒度 | 仅信号(”有变更“) | 操作类型 + 具体规则 |
| 接收端处理 | 全量 LoadPolicy() 重载 | 可增量更新对应规则 |
| 一致性 | 最终一致 | 最终一致,但延迟更低 |
| 实现复杂度 | 低 | 高 |
| 官方建议 | 简单场景 | 官方建议用 Dispatcher 替代 |
Watcher(基础接口)
工作模式:只传递”有策略变更“的信号,不携带变更内容。收到通知的节点全量 LoadPolicy() 重载
1 | SetUpdateCallback() — 注册收到通知后的回调(通常是 enforcer.LoadPolicy()) |
WatcherEx(扩展接口,继承 Watcher)
在基础接口上新增了 按操作类型区分 的通知方法
| API | 触发时机 |
|---|---|
| UpdateForAddPolicy() | AddPolicy / AddNamedPolicy / AddGroupingPolicy |
| UpdateForRemovePolicy() | RemovePolicy / RemoveNamedPolicy / RemoveGroupingPolicy |
| UpdateForRemoveFilteredPolicy() | RemoveFilteredPolicy / RemoveFilteredNamedPolicy |
| UpdateForSavePolicy() | SavePolicy |
| UpdateForAddPolicies() | AddPolicies / AddNamedPolicies / AddGroupingPolicies |
| UpdateForRemovePolicies() | RemovePolicies / RemoveNamedPolicies / RemoveGroupingPolicies |
优势:接收端可根据操作类型做增量更新,而非全量 LoadPolicy(),性能更好
支持的后端
| 类型 | 代表 |
|---|---|
| KV store | Redis、Redis WatcherEx、Etcd、TiKV |
| 消息系统 | Kafka、NATS、RabbitMQ、ZooKeeper、RocketMQ、GCP Pub/Sub、AWS SNS/SQS |
| 数据库 | PostgreSQL WatcherEx |
Dispatchers
Dispatcher 的职责:在多节点集群中,通过共识协议(如 Raft)传播增量策略变更,保证所有 Enforcer 实例最终看到相同的策略
与 Watcher 的本质区别
| 维度 | Watcher | Dispatcher |
|---|---|---|
| 同步协议 | Pub/Sub(消息广播,无确认) | Raft 共识(强一致,有日志) |
| 一致性保证 | 最终一致(消息可能丢失) | 强一致(Raft 保证多数派提交) |
| 初始状态 | 各节点独立加载初始策略 | 要求所有节点初始策略相同 |
| 增量同步 | WatcherEx 携带规则,Self 更新内存* | Dispatcher 实现 Casbin 内部钩子,统一分发 |
| 网络分区 | 分区期间各节点独立运行,可能不一致 | Raft 在分区时阻塞写入(保护一致性) |
| 实现复杂度 | 低(Pub/Sub 即可) | 高(需维护 Raft 集群) |
关键约束
- Dispatcher 只同步初始化之后的变更,不修复已有的不一致
- 用 Dispatcher 前,必须保证所有节点从相同的数据源(同一个 DB 快照)加载初始策略
DistributedEnforcer
专为 Dispatcher 场景设计的 Enforcer 变体
1 | DistributedEnforcer |
用法:
1 | e, _ := casbin.NewDistributedEnforcer("examples/basic_model.conf", "examples/basic_policy.csv") |
Role Managers
Role Manager 的职责:管理 RBAC 中”谁拥有哪个角色、角色如何继承“的层级关系。它是 g(user, role) 规则的执行引擎
两类 Role Manager
| 类型 | 数据来源 | 代表 |
|---|---|---|
| 内置(默认) | Casbin policy(g 规则,内存) | Default Role Manager |
| 外部集成 | LDAP / IdP 系统 | Okta、Auth0、Azure AD |
内置 Default Role Manager
- 从 policy 中的
g = _, _规则构建内存角色图 - 支持角色继承(g, alice, admin、g, admin, superadmin)
- 所有操作在内存中完成,速度最快
Session Role Manager
- 在默认 Role Manager 基础上扩展,支持基于时间范围的会话
- 即:某用户在某时间段内才拥有某角色(临时授权场景)
外部 Role Manager(Okta / Auth0)
- 直接查询 IdP 的角色/组数据,不依赖 Casbin policy 中的 g 规则
- 合企业已有统一身份系统、不想在 Casbin 维护一份重复角色数据的场景
Middleware
Middleware 的职责:将 enforcer.Enforce(sub, obj, act) 调用嵌入 Web 框架的请求处理链,免去每个 handler 手写鉴权样板代码
Go 生态覆盖范围 - 几乎所有主流 Go Web 框架都有对应插件
| 类型 | 代表框架 | Casbin 插件 |
|---|---|---|
| 通用 HTTP | Gin | gin-authz / gin-casbin |
| 全栈框架 | Beego、Revel、GoFrame | 内置 plugins/authz |
| 微服务 | Go kit、Kratos、go-zero | plugins/authz / tx7do/kratos-casbin |
| 高性能 | Fiber、FastHTTP、Hertz | casbin in gofiber/contrib |
| API 网关 | Traefik、Caddy、Tyk | casbin-forward-auth / caddy-authz |
| 轻量路由 | Chi、Negroni、Echo | chi-authz / echo-authz |





