1 介绍
1.1 定义
01.Casbin简介
a.基本定义
Casbin是一个强大且高效的权限管理库,支持多种访问控制模型。
b.项目来源
开源项目,支持Go、Java、Python等多种语言。
c.核心特点
模型和策略分离、支持多种模型、易于扩展。
02.权限管理概念
a.访问控制
控制用户对资源的访问权限。
b.策略Policy
定义谁可以访问什么资源。
c.模型Model
定义访问控制的规则和逻辑。
03.设计哲学
a.灵活性
支持多种权限模型,可自定义规则。
b.高性能
基于内存的策略匹配,响应迅速。
c.易用性
简洁的API设计,快速集成。
1.2 核心概念
01.PERM元素
a.Subject主体
发起访问请求的实体(用户、角色等)。
b.Object客体
被访问的资源(文件、API、数据等)。
c.Action动作
访问行为(read、write、delete等)。
d.Effect效果
访问结果(allow或deny)。
02.模型与策略
a.模型Model
定义访问控制逻辑的配置文件。
b.策略Policy
具体的权限规则数据。
c.分离设计
模型定义规则,策略存储数据。
03.基本工作流程
a.功能说明
展示Casbin的基本工作流程。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
// 创建enforcer
e, err := casbin.NewEnforcer("model.conf", "policy.csv")
if err != nil {
panic(err)
}
// 定义请求
sub := "alice" // 主体
obj := "data1" // 客体
act := "read" // 动作
// 执行权限检查
ok, err := e.Enforce(sub, obj, act)
if err != nil {
panic(err)
}
if ok {
fmt.Printf("%s 可以 %s %s\n", sub, act, obj)
} else {
fmt.Printf("%s 不能 %s %s\n", sub, act, obj)
}
}
---
04.核心组件
a.Enforcer执行器
权限检查的核心引擎。
b.Adapter适配器
策略的持久化存储。
c.Watcher观察者
分布式环境下的策略同步。
1.3 优缺点
01.主要优势
a.模型多样
支持ACL、RBAC、ABAC等多种模型。
b.语言无关
提供多种语言的实现版本。
c.性能优异
基于内存匹配,毫秒级响应。
d.易于集成
简洁的API,快速接入现有系统。
e.灵活扩展
支持自定义模型和函数。
02.主要限制
a.学习曲线
初次使用需要理解模型配置语法。
b.内存占用
策略全部加载到内存中。
c.复杂场景
超大规模策略需要优化。
03.适用场景
a.适合使用
需要灵活权限控制的应用、多租户系统、API网关。
b.不适合使用
超大规模策略(百万级以上)、实时策略更新要求极高的场景。
1.4 使用场景
01.Web应用权限
a.用户权限
控制用户访问不同页面和功能。
b.角色管理
基于角色的权限分配。
c.应用示例
a.功能说明
Web应用中的路由权限控制。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("rbac_model.conf", "rbac_policy.csv")
// 检查用户权限
users := []string{"alice", "bob", "charlie"}
resources := []string{"/admin", "/api/users", "/home"}
fmt.Println("Web路由权限检查:")
for _, user := range users {
for _, resource := range resources {
ok, _ := e.Enforce(user, resource, "GET")
status := "拒绝"
if ok {
status = "允许"
}
fmt.Printf("用户:%s 访问:%s -> %s\n", user, resource, status)
}
}
}
---
02.API权限控制
a.接口鉴权
控制API接口的访问权限。
b.RESTful权限
支持RESTful风格的权限定义。
c.限流控制
结合限流策略保护API。
03.多租户系统
a.租户隔离
不同租户的数据和权限隔离。
b.Domain支持
基于域的多租户权限管理。
c.多租户示例
a.功能说明
多租户环境下的权限隔离。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("domain_model.conf", "domain_policy.csv")
// 多租户权限检查
tenants := []string{"tenant1", "tenant2"}
user := "alice"
resource := "data"
fmt.Println("多租户权限检查:")
for _, tenant := range tenants {
ok, _ := e.Enforce(user, tenant, resource, "read")
status := "拒绝"
if ok {
status = "允许"
}
fmt.Printf("租户:%s 用户:%s 资源:%s -> %s\n", tenant, user, resource, status)
}
}
---
04.微服务鉴权
a.服务间鉴权
控制服务之间的调用权限。
b.网关集成
在API网关层统一鉴权。
1.5 架构原理
01.核心架构
a.分层设计
Enforcer → Model/Policy → Adapter → Storage。
b.组件交互
各组件职责明确,松耦合设计。
02.权限检查流程
a.请求接收
接收sub、obj、act等参数。
b.策略加载
从Adapter加载策略到内存。
c.规则匹配
根据Model定义的规则匹配策略。
d.结果返回
返回allow或deny。
03.内存管理
a.策略缓存
所有策略加载到内存中。
b.增量更新
支持动态添加删除策略。
c.内存优化
a.功能说明
大规模策略的内存优化策略。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 启用自动保存
e.EnableAutoSave(true)
// 添加策略
added, _ := e.AddPolicy("alice", "data1", "read")
fmt.Printf("策略添加: %v\n", added)
// 删除策略
removed, _ := e.RemovePolicy("alice", "data1", "read")
fmt.Printf("策略删除: %v\n", removed)
// 批量添加策略
rules := [][]string{
{"bob", "data2", "write"},
{"charlie", "data3", "read"},
}
e.AddPolicies(rules)
fmt.Println("批量添加完成")
// 保存策略
e.SavePolicy()
fmt.Println("策略已保存")
}
---
1.6 PERM模型
01.PERM定义
a.Policy策略
权限规则的具体数据。
b.Effect效果
策略的效果(allow或deny)。
c.Request请求
权限检查的请求参数。
d.Matcher匹配器
定义如何匹配请求和策略。
02.Model配置
a.request_definition
定义请求的参数结构。
b.policy_definition
定义策略的数据结构。
c.policy_effect
定义策略的效果逻辑。
d.matchers
定义匹配规则。
03.基本Model示例
a.功能说明
创建最简单的ACL模型配置。
b.代码示例
---
# model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
---
04.策略文件示例
a.功能说明
定义具体的权限策略数据。
b.代码示例
---
# policy.csv
p, alice, data1, read
p, alice, data2, write
p, bob, data2, read
p, bob, data3, write
p, charlie, data1, read
---
1.7 权限模型
01.ACL模型
a.访问控制列表
直接定义主体对客体的权限。
b.简单直接
适合小规模权限管理。
02.RBAC模型
a.基于角色
用户通过角色获得权限。
b.角色继承
支持角色层级关系。
c.RBAC示例
a.功能说明
实现基本的RBAC权限模型。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
// RBAC模型
e, _ := casbin.NewEnforcer("rbac_model.conf", "rbac_policy.csv")
// 添加角色
e.AddGroupingPolicy("alice", "admin")
e.AddGroupingPolicy("bob", "editor")
// 添加权限
e.AddPolicy("admin", "/admin", "GET")
e.AddPolicy("editor", "/api/posts", "POST")
// 检查权限
users := []string{"alice", "bob"}
for _, user := range users {
ok1, _ := e.Enforce(user, "/admin", "GET")
ok2, _ := e.Enforce(user, "/api/posts", "POST")
fmt.Printf("%s - admin访问:%v, post编辑:%v\n", user, ok1, ok2)
}
// 获取用户角色
roles, _ := e.GetRolesForUser("alice")
fmt.Printf("alice的角色: %v\n", roles)
}
---
03.ABAC模型
a.基于属性
根据主体、客体的属性进行判断。
b.灵活性高
适合复杂的业务场景。
04.RESTful模型
a.RESTful风格
支持路径匹配和HTTP方法。
b.通配符
支持*、:等通配符。
05.混合模型
a.多模型组合
结合RBAC和ABAC的优势。
b.自定义规则
根据业务需求定制模型。
2 核心组件
2.1 汇总:5个
01.Enforcer执行器
a.核心引擎
负责权限检查的主要逻辑。
b.API接口
提供权限检查和策略管理API。
02.Model模型
a.配置文件
定义权限模型的规则。
b.语法定义
使用PERM语法描述模型。
03.Policy策略
a.权限数据
存储具体的权限规则。
b.持久化
通过Adapter进行存储。
04.Adapter适配器
a.存储接口
负责策略的读取和保存。
b.多种实现
支持文件、数据库、Redis等。
05.Matcher匹配器
a.规则匹配
定义请求和策略的匹配逻辑。
b.自定义函数
支持自定义匹配函数。
2.2 Enforcer执行器
01.创建Enforcer
a.NewEnforcer
使用模型和策略文件创建。
b.NewEnforcerSafe
线程安全版本的Enforcer。
c.创建示例
a.功能说明
创建和配置Enforcer实例。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
)
func main() {
// 方式1: 使用文件创建
e1, err := casbin.NewEnforcer("model.conf", "policy.csv")
if err != nil {
panic(err)
}
// 方式2: 使用字符串创建Model
modelText := `
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
`
m, _ := model.NewModelFromString(modelText)
e2, _ := casbin.NewEnforcer(m)
// 手动添加策略
e2.AddPolicy("alice", "data1", "read")
e2.AddPolicy("bob", "data2", "write")
// 测试权限
ok, _ := e2.Enforce("alice", "data1", "read")
fmt.Printf("Alice read data1: %v\n", ok)
}
---
02.权限检查
a.Enforce方法
执行权限检查,返回是否允许。
b.EnforceWithMatcher
使用自定义匹配器检查。
c.BatchEnforce
批量检查多个权限请求。
03.Enforcer配置
a.EnableLog
启用日志输出。
b.EnableAutoSave
自动保存策略变更。
c.EnableEnforce
启用或禁用权限检查。
2.3 Model模型
01.Model配置文件
a.request_definition
定义请求参数格式。
b.policy_definition
定义策略数据格式。
c.role_definition
定义角色继承关系。
d.policy_effect
定义策略效果逻辑。
e.matchers
定义匹配规则表达式。
02.Model语法
a.变量定义
使用r、p、g等变量。
b.表达式
支持逻辑运算符&&、||、!。
c.函数调用
支持内置函数和自定义函数。
03.自定义Model
a.功能说明
创建自定义权限模型。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
)
func main() {
// 自定义RBAC with domains模型
modelText := `
[request_definition]
r = sub, dom, obj, act
[policy_definition]
p = sub, dom, obj, act
[role_definition]
g = _, _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
`
m, _ := model.NewModelFromString(modelText)
e, _ := casbin.NewEnforcer(m)
// 添加域内角色
e.AddGroupingPolicy("alice", "admin", "domain1")
e.AddGroupingPolicy("bob", "user", "domain2")
// 添加权限
e.AddPolicy("admin", "domain1", "data", "read")
e.AddPolicy("user", "domain2", "data", "read")
// 检查跨域权限
ok1, _ := e.Enforce("alice", "domain1", "data", "read")
ok2, _ := e.Enforce("alice", "domain2", "data", "read")
fmt.Printf("Alice in domain1: %v\n", ok1)
fmt.Printf("Alice in domain2: %v\n", ok2)
}
---
2.4 Policy策略
01.策略格式
a.CSV格式
使用逗号分隔的策略数据。
b.策略类型
p为权限策略,g为角色策略。
02.策略操作
a.AddPolicy
添加单条策略。
b.AddPolicies
批量添加策略。
c.RemovePolicy
删除单条策略。
d.RemoveFilteredPolicy
按条件删除策略。
03.策略管理示例
a.功能说明
完整的策略增删改查操作。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("rbac_model.conf", "rbac_policy.csv")
// 添加策略
added, _ := e.AddPolicy("alice", "data1", "read")
fmt.Printf("策略添加: %v\n", added)
// 批量添加
rules := [][]string{
{"bob", "data2", "write"},
{"charlie", "data3", "read"},
}
e.AddPolicies(rules)
// 获取所有策略
policies := e.GetPolicy()
fmt.Println("所有策略:")
for _, p := range policies {
fmt.Printf(" %v\n", p)
}
// 删除策略
removed, _ := e.RemovePolicy("alice", "data1", "read")
fmt.Printf("策略删除: %v\n", removed)
// 按条件删除
e.RemoveFilteredPolicy(1, "data2")
fmt.Println("已删除所有data2相关策略")
// 检查策略是否存在
has := e.HasPolicy("bob", "data2", "write")
fmt.Printf("Bob对data2的写权限存在: %v\n", has)
}
---
04.角色策略
a.AddGroupingPolicy
添加角色继承关系。
b.GetRolesForUser
获取用户的所有角色。
c.GetUsersForRole
获取角色下的所有用户。
2.5 Adapter适配器
01.适配器接口
a.LoadPolicy
从存储加载策略到内存。
b.SavePolicy
保存策略到存储。
c.AddPolicy
添加策略到存储。
d.RemovePolicy
从存储删除策略。
02.内置适配器
a.FileAdapter
基于文件的适配器。
b.MemoryAdapter
基于内存的适配器。
03.第三方适配器
a.数据库适配器
支持MySQL、PostgreSQL、MongoDB等。
b.缓存适配器
支持Redis、Memcached等。
04.适配器使用
a.功能说明
使用文件适配器管理策略。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
fileadapter "github.com/casbin/casbin/v2/persist/file-adapter"
)
func main() {
// 创建文件适配器
adapter := fileadapter.NewAdapter("policy.csv")
// 使用适配器创建Enforcer
e, err := casbin.NewEnforcer("model.conf", adapter)
if err != nil {
panic(err)
}
// 添加策略
e.AddPolicy("alice", "data1", "read")
e.AddPolicy("bob", "data2", "write")
// 保存到文件
err = e.SavePolicy()
if err != nil {
fmt.Printf("保存策略失败: %v\n", err)
return
}
fmt.Println("策略已保存到文件")
// 重新加载策略
err = e.LoadPolicy()
if err != nil {
fmt.Printf("加载策略失败: %v\n", err)
return
}
fmt.Println("策略已从文件加载")
// 验证策略
policies := e.GetPolicy()
fmt.Printf("当前策略数量: %d\n", len(policies))
}
---
2.6 Matcher匹配器
01.匹配器语法
a.比较运算符
==、!=、>、<、>=、<=。
b.逻辑运算符
&&、||、!。
c.函数调用
支持内置函数和自定义函数。
02.内置匹配函数
a.keyMatch
路径通配符匹配。
b.keyMatch2
支持:参数的路径匹配。
c.regexMatch
正则表达式匹配。
d.ipMatch
IP地址匹配。
03.自定义匹配函数
a.功能说明
注册自定义匹配函数。
b.代码示例
---
package main
import (
"fmt"
"strings"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/util"
)
// 自定义匹配函数
func customMatch(key1, key2 string) bool {
return strings.HasPrefix(key1, key2)
}
func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 注册自定义函数
e.AddFunction("customMatch", customMatch)
// 修改模型使用自定义函数
// [matchers]
// m = r.sub == p.sub && customMatch(r.obj, p.obj) && r.act == p.act
e.AddPolicy("alice", "data", "read")
// 测试自定义匹配
ok, _ := e.Enforce("alice", "data123", "read")
fmt.Printf("自定义匹配结果: %v\n", ok)
// 使用内置keyMatch
e2, _ := casbin.NewEnforcer("keymatch_model.conf", "keymatch_policy.csv")
e2.AddPolicy("alice", "/api/*", "GET")
ok2, _ := e2.Enforce("alice", "/api/users", "GET")
fmt.Printf("KeyMatch结果: %v\n", ok2)
}
---
04.高级匹配
a.RESTful匹配
支持RESTful路径和HTTP方法。
b.通配符匹配
支持*、:等通配符。
c.正则匹配
支持复杂的正则表达式。
3 权限模型
3.1 ACL模型
01.ACL基本概念
a.访问控制列表
直接指定主体对客体的访问权限。
b.简单直接
不需要角色概念,权限关系清晰。
02.ACL模型配置
a.功能说明
配置最基本的ACL权限模型。
b.代码示例
---
# acl_model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
---
03.ACL实现
a.功能说明
使用ACL模型进行权限控制。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("acl_model.conf", "acl_policy.csv")
// 添加ACL策略
e.AddPolicy("alice", "data1", "read")
e.AddPolicy("alice", "data2", "write")
e.AddPolicy("bob", "data2", "read")
// 权限检查
users := []string{"alice", "bob"}
resources := []string{"data1", "data2"}
actions := []string{"read", "write"}
fmt.Println("ACL权限检查:")
for _, user := range users {
for _, res := range resources {
for _, act := range actions {
ok, _ := e.Enforce(user, res, act)
if ok {
fmt.Printf("%s可以%s %s\n", user, act, res)
}
}
}
}
}
---
3.2 RBAC模型
01.RBAC基本概念
a.基于角色
用户通过角色获得权限。
b.角色继承
支持角色之间的继承关系。
c.易于管理
通过角色统一管理权限。
02.RBAC模型配置
a.功能说明
配置支持角色继承的RBAC模型。
b.代码示例
---
# rbac_model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
---
03.RBAC实现
a.功能说明
实现完整的RBAC权限系统。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("rbac_model.conf", "rbac_policy.csv")
// 定义角色
e.AddGroupingPolicy("alice", "admin")
e.AddGroupingPolicy("bob", "editor")
e.AddGroupingPolicy("charlie", "viewer")
// 定义角色权限
e.AddPolicy("admin", "/*", "*")
e.AddPolicy("editor", "/api/posts", "POST")
e.AddPolicy("editor", "/api/posts", "PUT")
e.AddPolicy("viewer", "/api/posts", "GET")
// 角色继承
e.AddGroupingPolicy("editor", "viewer")
// 测试权限
fmt.Println("RBAC权限测试:")
// Alice (admin)
fmt.Println("\nAlice (admin):")
ok, _ := e.Enforce("alice", "/admin", "GET")
fmt.Printf(" 访问/admin: %v\n", ok)
// Bob (editor, 继承viewer)
fmt.Println("\nBob (editor):")
ok, _ = e.Enforce("bob", "/api/posts", "POST")
fmt.Printf(" POST /api/posts: %v\n", ok)
ok, _ = e.Enforce("bob", "/api/posts", "GET")
fmt.Printf(" GET /api/posts (继承): %v\n", ok)
// Charlie (viewer)
fmt.Println("\nCharlie (viewer):")
ok, _ = e.Enforce("charlie", "/api/posts", "GET")
fmt.Printf(" GET /api/posts: %v\n", ok)
ok, _ = e.Enforce("charlie", "/api/posts", "POST")
fmt.Printf(" POST /api/posts: %v\n", ok)
// 获取用户角色
roles, _ := e.GetRolesForUser("bob")
fmt.Printf("\nBob的所有角色: %v\n", roles)
}
---
04.角色层级
a.多级继承
支持多层角色继承关系。
b.隐式角色
通过继承获得的隐式权限。
3.3 ABAC模型
01.ABAC基本概念
a.基于属性
根据主体、客体、环境的属性判断权限。
b.灵活性高
可以实现复杂的业务规则。
c.属性类型
用户属性、资源属性、环境属性。
02.ABAC模型配置
a.功能说明
配置基于属性的访问控制模型。
b.代码示例
---
# abac_model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub_rule, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = eval(p.sub_rule) && r.obj == p.obj && r.act == p.act
---
03.ABAC实现
a.功能说明
使用属性规则进行权限判断。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
// 用户结构
type User struct {
Name string
Age int
Department string
}
func main() {
e, _ := casbin.NewEnforcer("abac_model.conf")
// 添加ABAC策略(基于属性的规则)
e.AddPolicy("r.sub.Age >= 18", "adult_content", "read")
e.AddPolicy("r.sub.Department == 'IT'", "server_config", "write")
// 测试用户
alice := User{Name: "alice", Age: 20, Department: "IT"}
bob := User{Name: "bob", Age: 16, Department: "HR"}
// 构造请求对象
fmt.Println("ABAC权限测试:")
// 这里简化演示,实际需要将属性传入Enforce
// Casbin支持通过自定义函数访问对象属性
fmt.Printf("Alice(20岁,IT部门) 访问adult_content: true\n")
fmt.Printf("Bob(16岁,HR部门) 访问adult_content: false\n")
fmt.Printf("Alice 修改server_config: true\n")
fmt.Printf("Bob 修改server_config: false\n")
}
---
04.属性函数
a.自定义属性
定义获取属性的函数。
b.复杂规则
支持复杂的属性表达式。
3.4 RESTful模型
01.RESTful概念
a.路径匹配
支持RESTful风格的URL路径。
b.HTTP方法
支持GET、POST、PUT、DELETE等。
c.通配符
支持*和:参数匹配。
02.RESTful模型配置
a.功能说明
配置支持RESTful路径匹配的模型。
b.代码示例
---
# restful_model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && keyMatch2(r.obj, p.obj) && r.act == p.act
---
03.RESTful实现
a.功能说明
实现RESTful API权限控制。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("restful_model.conf", "restful_policy.csv")
// 添加RESTful策略
e.AddPolicy("alice", "/api/users", "GET")
e.AddPolicy("alice", "/api/users/:id", "GET")
e.AddPolicy("alice", "/api/posts/*", "GET")
e.AddPolicy("bob", "/api/users", "POST")
e.AddPolicy("bob", "/api/users/:id", "PUT")
e.AddPolicy("bob", "/api/users/:id", "DELETE")
// 测试路径匹配
testCases := []struct {
user string
path string
method string
}{
{"alice", "/api/users", "GET"},
{"alice", "/api/users/123", "GET"},
{"alice", "/api/posts/456/comments", "GET"},
{"alice", "/api/users", "POST"},
{"bob", "/api/users", "POST"},
{"bob", "/api/users/123", "PUT"},
{"bob", "/api/users/456", "DELETE"},
}
fmt.Println("RESTful权限测试:")
for _, tc := range testCases {
ok, _ := e.Enforce(tc.user, tc.path, tc.method)
status := "拒绝"
if ok {
status = "允许"
}
fmt.Printf("%s %s %s -> %s\n", tc.user, tc.method, tc.path, status)
}
}
---
04.路径匹配函数
a.keyMatch
简单通配符匹配。
b.keyMatch2
支持:参数匹配。
c.keyMatch3
支持{param}参数匹配。
3.5 自定义模型
01.模型扩展
a.组合模型
结合多种模型的优势。
b.业务规则
集成特定的业务逻辑。
02.自定义函数
a.注册函数
向Enforcer注册自定义函数。
b.函数使用
在Matcher中调用自定义函数。
03.复杂模型实现
a.功能说明
实现支持时间、IP等条件的复杂模型。
b.代码示例
---
package main
import (
"fmt"
"strings"
"time"
"github.com/casbin/casbin/v2"
)
// 自定义函数:时间范围检查
func timeRangeMatch(timeStr, startStr, endStr string) bool {
layout := "15:04"
t, _ := time.Parse(layout, timeStr)
start, _ := time.Parse(layout, startStr)
end, _ := time.Parse(layout, endStr)
return !t.Before(start) && !t.After(end)
}
// 自定义函数:IP段匹配
func ipRangeMatch(ip, ipRange string) bool {
return strings.HasPrefix(ip, ipRange)
}
func main() {
// 自定义模型文本
modelText := `
[request_definition]
r = sub, obj, act, time, ip
[policy_definition]
p = sub, obj, act, time_start, time_end, ip_range
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act && timeRangeMatch(r.time, p.time_start, p.time_end) && ipRangeMatch(r.ip, p.ip_range)
`
e, _ := casbin.NewEnforcerSafe(modelText)
// 注册自定义函数
e.AddFunction("timeRangeMatch", timeRangeMatch)
e.AddFunction("ipRangeMatch", ipRangeMatch)
// 添加策略:alice在9:00-18:00,从192.168.1.*可以读取data
e.AddPolicy("alice", "data", "read", "09:00", "18:00", "192.168.1")
// 测试不同条件
fmt.Println("复杂模型权限测试:")
// 在时间范围内,IP匹配
ok, _ := e.Enforce("alice", "data", "read", "14:30", "192.168.1.100")
fmt.Printf("14:30, 192.168.1.100: %v\n", ok)
// 在时间范围外
ok, _ = e.Enforce("alice", "data", "read", "20:00", "192.168.1.100")
fmt.Printf("20:00, 192.168.1.100: %v\n", ok)
// IP不匹配
ok, _ = e.Enforce("alice", "data", "read", "14:30", "10.0.0.1")
fmt.Printf("14:30, 10.0.0.1: %v\n", ok)
}
---
04.模型设计原则
a.简洁性
保持模型简单易懂。
b.可维护性
便于后续修改和扩展。
c.性能考虑
避免复杂的计算逻辑。
4 策略管理
4.1 策略定义
01.策略格式
a.CSV格式
使用逗号分隔的字段。
b.策略类型
p为权限策略,g为角色继承策略。
c.字段说明
每个字段对应Model中定义的变量。
02.策略文件示例
a.功能说明
定义完整的策略文件格式。
b.代码示例
---
# policy.csv
# 权限策略 (p, sub, obj, act)
p, alice, data1, read
p, alice, data2, write
p, bob, data2, read
p, data2_admin, data2, read
p, data2_admin, data2, write
# 角色继承 (g, user, role)
g, alice, admin
g, bob, data2_admin
---
03.策略规则
a.主体规则
定义用户或角色。
b.客体规则
定义资源对象。
c.动作规则
定义允许的操作。
4.2 策略添加
01.添加单条策略
a.AddPolicy
添加权限策略。
b.AddGroupingPolicy
添加角色继承策略。
02.批量添加
a.AddPolicies
批量添加多条策略。
b.性能优化
批量操作比单条操作更高效。
03.策略添加示例
a.功能说明
演示多种策略添加方式。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 添加单条策略
added, _ := e.AddPolicy("alice", "data1", "read")
fmt.Printf("添加策略: %v\n", added)
// 批量添加策略
rules := [][]string{
{"bob", "data2", "write"},
{"charlie", "data3", "read"},
{"david", "data4", "delete"},
}
added, _ = e.AddPolicies(rules)
fmt.Printf("批量添加: %v\n", added)
// 添加角色
e.AddGroupingPolicy("alice", "admin")
e.AddGroupingPolicy("bob", "editor")
// 添加命名策略(多类型策略)
e.AddNamedPolicy("p", "alice", "data5", "read")
e.AddNamedGroupingPolicy("g", "charlie", "viewer")
// 检查策略数量
policyCount := len(e.GetPolicy())
roleCount := len(e.GetGroupingPolicy())
fmt.Printf("策略数: %d, 角色数: %d\n", policyCount, roleCount)
// 保存到文件
e.SavePolicy()
fmt.Println("策略已保存")
}
---
4.3 策略删除
01.删除单条策略
a.RemovePolicy
删除指定的权限策略。
b.RemoveGroupingPolicy
删除角色继承关系。
02.批量删除
a.RemovePolicies
批量删除多条策略。
b.RemoveFilteredPolicy
按条件过滤删除策略。
03.策略删除示例
a.功能说明
演示各种策略删除方法。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 添加测试策略
e.AddPolicy("alice", "data1", "read")
e.AddPolicy("alice", "data2", "write")
e.AddPolicy("bob", "data1", "read")
e.AddPolicy("bob", "data2", "read")
fmt.Printf("初始策略数: %d\n", len(e.GetPolicy()))
// 删除单条策略
removed, _ := e.RemovePolicy("alice", "data1", "read")
fmt.Printf("删除单条: %v\n", removed)
// 批量删除
rules := [][]string{
{"bob", "data1", "read"},
{"bob", "data2", "read"},
}
removed, _ = e.RemovePolicies(rules)
fmt.Printf("批量删除: %v\n", removed)
// 按条件删除 (删除所有data2相关)
removed, _ = e.RemoveFilteredPolicy(1, "data2")
fmt.Printf("条件删除: %v\n", removed)
// 删除角色
e.AddGroupingPolicy("alice", "admin")
e.RemoveGroupingPolicy("alice", "admin")
fmt.Printf("最终策略数: %d\n", len(e.GetPolicy()))
e.SavePolicy()
}
---
4.4 策略更新
01.更新策略
a.删除后添加
通过删除旧策略再添加新策略实现更新。
b.UpdatePolicy
直接更新策略(如果适配器支持)。
02.策略更新示例
a.功能说明
更新已有策略的内容。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 添加初始策略
e.AddPolicy("alice", "data1", "read")
fmt.Println("原始策略: alice, data1, read")
// 更新策略 (修改权限)
oldPolicy := []string{"alice", "data1", "read"}
newPolicy := []string{"alice", "data1", "write"}
updated, _ := e.UpdatePolicy(oldPolicy, newPolicy)
fmt.Printf("策略更新: %v\n", updated)
// 验证更新
canRead, _ := e.Enforce("alice", "data1", "read")
canWrite, _ := e.Enforce("alice", "data1", "write")
fmt.Printf("Alice read data1: %v\n", canRead)
fmt.Printf("Alice write data1: %v\n", canWrite)
// 批量更新
oldPolicies := [][]string{
{"alice", "data1", "write"},
}
newPolicies := [][]string{
{"alice", "data1", "delete"},
}
e.UpdatePolicies(oldPolicies, newPolicies)
e.SavePolicy()
}
---
4.5 策略查询
01.查询所有策略
a.GetPolicy
获取所有权限策略。
b.GetGroupingPolicy
获取所有角色策略。
02.条件查询
a.GetFilteredPolicy
按条件过滤查询策略。
b.HasPolicy
检查策略是否存在。
03.策略查询示例
a.功能说明
演示各种策略查询方法。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 添加测试数据
e.AddPolicy("alice", "data1", "read")
e.AddPolicy("alice", "data2", "write")
e.AddPolicy("bob", "data1", "read")
e.AddGroupingPolicy("alice", "admin")
// 获取所有策略
policies := e.GetPolicy()
fmt.Println("所有权限策略:")
for _, p := range policies {
fmt.Printf(" %v\n", p)
}
// 获取所有角色
roles := e.GetGroupingPolicy()
fmt.Println("\n所有角色:")
for _, r := range roles {
fmt.Printf(" %v\n", r)
}
// 条件查询
filtered := e.GetFilteredPolicy(0, "alice")
fmt.Println("\nAlice的所有权限:")
for _, p := range filtered {
fmt.Printf(" %v\n", p)
}
// 检查策略存在
has := e.HasPolicy("alice", "data1", "read")
fmt.Printf("\n策略存在: %v\n", has)
// 获取用户角色
userRoles, _ := e.GetRolesForUser("alice")
fmt.Printf("Alice的角色: %v\n", userRoles)
// 获取角色用户
users, _ := e.GetUsersForRole("admin")
fmt.Printf("Admin角色的用户: %v\n", users)
}
---
4.6 策略持久化
01.策略保存
a.SavePolicy
保存策略到存储。
b.自动保存
EnableAutoSave开启自动保存。
02.策略加载
a.LoadPolicy
从存储加载策略。
b.初始化加载
创建Enforcer时自动加载。
03.持久化示例
a.功能说明
演示策略的持久化操作。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
// 创建enforcer并加载策略
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
// 启用自动保存
e.EnableAutoSave(true)
// 添加策略 (自动保存)
e.AddPolicy("alice", "data1", "read")
fmt.Println("策略已自动保存")
// 手动保存
e.EnableAutoSave(false)
e.AddPolicy("bob", "data2", "write")
err := e.SavePolicy()
if err != nil {
fmt.Printf("保存失败: %v\n", err)
} else {
fmt.Println("策略已手动保存")
}
// 重新加载策略
err = e.LoadPolicy()
if err != nil {
fmt.Printf("加载失败: %v\n", err)
} else {
fmt.Println("策略已重新加载")
}
// 清空内存策略
e.ClearPolicy()
fmt.Printf("清空后策略数: %d\n", len(e.GetPolicy()))
// 再次加载
e.LoadPolicy()
fmt.Printf("重新加载后策略数: %d\n", len(e.GetPolicy()))
}
---
5 高级特性
5.1 角色继承
01.角色继承概念
a.层级关系
角色可以继承其他角色的权限。
b.传递性
支持多层继承关系。
02.角色继承实现
a.功能说明
实现多层角色继承。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("rbac_model.conf")
// 定义角色层级
e.AddGroupingPolicy("alice", "manager")
e.AddGroupingPolicy("manager", "employee")
e.AddGroupingPolicy("employee", "user")
// 定义权限
e.AddPolicy("user", "/home", "read")
e.AddPolicy("employee", "/api/data", "read")
e.AddPolicy("manager", "/api/reports", "read")
// 测试继承
fmt.Println("角色继承测试:")
ok, _ := e.Enforce("alice", "/home", "read")
fmt.Printf("Alice访问/home: %v (从user继承)\n", ok)
ok, _ = e.Enforce("alice", "/api/data", "read")
fmt.Printf("Alice访问/api/data: %v (从employee继承)\n", ok)
ok, _ = e.Enforce("alice", "/api/reports", "read")
fmt.Printf("Alice访问/api/reports: %v (manager直接权限)\n", ok)
// 获取所有角色
roles, _ := e.GetImplicitRolesForUser("alice")
fmt.Printf("\nAlice的所有角色(含继承): %v\n", roles)
}
---
5.2 多Domain
01.Domain概念
a.域隔离
不同域之间权限隔离。
b.多租户
适用于多租户系统。
02.Domain模型
a.功能说明
实现基于域的权限控制。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, _ := casbin.NewEnforcer("domain_model.conf")
// 添加不同域的角色
e.AddGroupingPolicy("alice", "admin", "tenant1")
e.AddGroupingPolicy("alice", "user", "tenant2")
e.AddGroupingPolicy("bob", "admin", "tenant2")
// 添加域权限
e.AddPolicy("admin", "tenant1", "/data", "write")
e.AddPolicy("admin", "tenant2", "/data", "write")
e.AddPolicy("user", "tenant2", "/data", "read")
// 跨域测试
fmt.Println("多Domain测试:")
ok, _ := e.Enforce("alice", "tenant1", "/data", "write")
fmt.Printf("Alice在tenant1写/data: %v\n", ok)
ok, _ = e.Enforce("alice", "tenant2", "/data", "write")
fmt.Printf("Alice在tenant2写/data: %v\n", ok)
ok, _ = e.Enforce("alice", "tenant2", "/data", "read")
fmt.Printf("Alice在tenant2读/data: %v\n", ok)
// 获取域内角色
roles, _ := e.GetRolesForUserInDomain("alice", "tenant1")
fmt.Printf("\nAlice在tenant1的角色: %v\n", roles)
}
---
5.3 优先级
01.策略优先级
a.优先级规则
定义策略的执行优先级。
b.冲突解决
高优先级策略优先生效。
02.优先级实现
a.功能说明
使用优先级解决策略冲突。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
// 带优先级的模型
modelText := `
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act, eft
[policy_effect]
e = priority(p.eft) || deny
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
`
e, _ := casbin.NewEnforcerSafe(modelText)
// 添加冲突策略
e.AddPolicy("alice", "data", "read", "deny")
e.AddPolicy("alice", "data", "read", "allow")
// 设置策略优先级
e.EnableEnforce(true)
ok, _ := e.Enforce("alice", "data", "read")
fmt.Printf("优先级测试 (allow优先): %v\n", ok)
}
---
6 适配器
6.1 文件适配器
01.文件适配器
a.FileAdapter
基于CSV文件的适配器。
b.简单易用
适合小规模应用。
02.文件适配器使用
a.功能说明
使用文件适配器管理策略。
b.代码示例
---
package main
import (
"github.com/casbin/casbin/v2"
fileadapter "github.com/casbin/casbin/v2/persist/file-adapter"
)
func main() {
adapter := fileadapter.NewAdapter("policy.csv")
e, _ := casbin.NewEnforcer("model.conf", adapter)
e.AddPolicy("alice", "data", "read")
e.SavePolicy()
}
---
6.2 数据库适配器
01.数据库适配器
a.GORM Adapter
支持MySQL、PostgreSQL、SQLite等。
b.持久化
策略保存到数据库。
02.数据库适配器使用
a.功能说明
使用MySQL适配器。
b.代码示例
---
package main
import (
"github.com/casbin/casbin/v2"
gormadapter "github.com/casbin/gorm-adapter/v3"
_ "github.com/go-sql-driver/mysql"
)
func main() {
adapter, _ := gormadapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/casbin")
e, _ := casbin.NewEnforcer("model.conf", adapter)
e.AddPolicy("alice", "data", "read")
e.SavePolicy()
}
---
7 实战应用
7.1 安装配置
01.安装Casbin
a.go get安装
获取Casbin库。
b.代码示例
---
go get github.com/casbin/casbin/v2
---
02.基本配置
a.模型文件
创建model.conf。
b.策略文件
创建policy.csv。
03.快速开始
a.功能说明
最小化Casbin应用。
b.代码示例
---
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, err := casbin.NewEnforcer("model.conf", "policy.csv")
if err != nil {
panic(err)
}
sub := "alice"
obj := "data1"
act := "read"
ok, _ := e.Enforce(sub, obj, act)
if ok {
fmt.Println("允许访问")
} else {
fmt.Println("拒绝访问")
}
}
---
7.2 Web框架集成
01.Gin集成
a.中间件
创建Casbin中间件。
b.路由保护
保护需要权限的路由。
02.Gin集成示例
a.功能说明
在Gin框架中集成Casbin。
b.代码示例
---
package main
import (
"github.com/casbin/casbin/v2"
"github.com/gin-gonic/gin"
"net/http"
)
func CasbinMiddleware(e *casbin.Enforcer) gin.HandlerFunc {
return func(c *gin.Context) {
user := c.GetHeader("User")
path := c.Request.URL.Path
method := c.Request.Method
ok, _ := e.Enforce(user, path, method)
if !ok {
c.JSON(http.StatusForbidden, gin.H{"error": "权限不足"})
c.Abort()
return
}
c.Next()
}
}
func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
r := gin.Default()
r.Use(CasbinMiddleware(e))
r.GET("/api/data", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"data": "sensitive data"})
})
r.Run(":8080")
}
---