go casbin访问权限控制

casbin

一.常用API

Casbin 在 Go 里常用的 API,这些 API 都是围绕 Enforcer(执行器)来操作的。


1. Enforcer 初始化

1
2
3
4
5
6
7
8
9
// 从模型文件 + 策略文件
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")

// 从模型文件 + Adapter(如 MySQL)
a, _ := gormadapter.NewAdapter("mysql", "root:123@tcp(127.0.0.1:3306)/")
e, _ := casbin.NewEnforcer("model.conf", a)

// 加载策略(必须调用)
e.LoadPolicy()

2. 权限校验

1
2
3
4
5
6
ok, err := e.Enforce("alice", "data1", "read")
if ok {
fmt.Println("允许访问")
} else {
fmt.Println("拒绝访问")
}

3. 策略管理 API

添加策略

1
2
3
4
5
// 添加一个权限策略
e.AddPolicy("alice", "data1", "read")

// 添加角色继承关系(RBAC)
e.AddGroupingPolicy("alice", "admin")
删除策略
1
2
3
4
5
// 删除某个策略
e.RemovePolicy("alice", "data1", "read")

// 删除某个角色继承关系
e.RemoveGroupingPolicy("alice", "admin")

批量操作

1
2
3
4
5
6
7
8
9
10
11
// 批量添加
e.AddPolicies([][]string{
{"bob", "data2", "write"},
{"tom", "data3", "read"},
})

// 批量删除
e.RemovePolicies([][]string{
{"bob", "data2", "write"},
{"tom", "data3", "read"},
})

4. 查询策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 获取所有策略
policies := e.GetPolicy()

// 获取所有角色继承关系
grouping := e.GetGroupingPolicy()

// 获取用户的角色
roles, _ := e.GetRolesForUser("alice")

// 获取角色下的用户
users, _ := e.GetUsersForRole("admin")

// 获取某用户的所有权限
perms, _ := e.GetPermissionsForUser("alice")

5. 保存与同步

1
2
3
4
5
// 保存策略到持久化存储(文件/数据库)
e.SavePolicy()

// 清空所有策略
e.ClearPolicy()

6. 更新策略

1
2
3
4
5
// 更新策略:把 (alice,data1,read) 替换为 (alice,data1,write)
e.UpdatePolicy(
[]string{"alice", "data1", "read"},
[]string{"alice", "data1", "write"},
)

7. RBAC 相关 API

1
2
3
4
5
6
7
8
9
10
11
// 给用户添加角色
e.AddRoleForUser("alice", "admin")

// 删除用户的某个角色
e.DeleteRoleForUser("alice", "admin")

// 删除用户的所有角色
e.DeleteRolesForUser("alice")

// 获取某角色的所有权限
e.GetPermissionsForUser("admin")

8. 临时禁用缓存

Casbin 会缓存 Enforce 的结果,你可以清理缓存:

1
e.InvalidateCache()

9. 自定义函数(高级)

Casbin 支持在 matchers 里使用自定义函数:

1
e.AddFunction("KeyMatch", util.KeyMatchFunc)

常用的有 KeyMatchRegexMatch,用于 RESTful 路径匹配。


总结

Casbin 常用 API 可以分为几类:

  1. Enforce:权限校验
  2. Policy 管理:AddPolicy、RemovePolicy、UpdatePolicy
  3. 角色管理:AddRoleForUser、GetRolesForUser、GetUsersForRole
  4. 查询:GetPolicy、GetPermissionsForUser
  5. 持久化:LoadPolicy、SavePolicy、ClearPolicy
  6. 高级:自定义 matcher 函数、缓存控制

二.快速入门


1. Casbin 的核心概念

Casbin 主要有 三部分核心内容

  1. Model(模型)

    • 定义权限控制的逻辑规则,比如 “角色能访问哪些资源”、”用户是否可以写资源”。
    • 使用 .conf 文件来描述。

    示例(RBAC 模型):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [request_definition]
    r = sub, obj, act # 请求定义:主体(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
  2. Policy(策略/规则)

    • 定义谁拥有什么权限,通常写在 .csv 文件里。
    • 可以存储在文件、数据库(MySQL、Postgres)、Redis、Etcd 等中。

    示例(policy.csv):

    1
    2
    3
    p, alice, data1, read   # Alice 可以读 data1
    p, bob, data2, write # Bob 可以写 data2
    g, alice, admin # Alice 是 admin 角色
  3. Enforcer(执行器)

    • Casbin 的核心引擎,负责加载模型、策略,然后根据请求判断是否允许。
    • 使用 Enforce(sub, obj, act) 来做权限校验。

2. Casbin 的权限控制模型

Casbin 支持多种控制方式:

  1. ACL(Access Control List,访问控制列表)
    每个用户单独配置资源访问权限。
  2. RBAC(Role-Based Access Control,基于角色的权限控制)
    用户 -> 角色 -> 权限,常见于企业系统。
  3. ABAC(Attribute-Based Access Control,基于属性的权限控制)
    根据用户、资源、请求的属性动态决定是否允许,比如时间段、IP、部门等。

3. Casbin 工作流程

  1. 你定义 Model(控制逻辑)
  2. 你配置 Policy(权限规则)
  3. 你用 Enforcer 来加载 model + policy
  4. 每次请求时调用 Enforce 判断是否允许

流程图大概是这样:

1
Request(sub,obj,act) → Enforcer → Model+Policy → Allow/Deny

4. 使用示例

(1) 安装

1
go get github.com/casbin/casbin/v2

(2) 最简单的 Demo

目录结构:

1
2
3
4
.
├── model.conf
├── policy.csv
└── main.go

model.conf

1
2
3
4
5
6
7
8
9
10
11
[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

policy.csv

1
2
p, alice, data1, read
p, bob, data2, write

main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
"fmt"

"github.com/casbin/casbin/v2"
)

func main() {
// 加载模型和策略
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")

// 请求判断
sub := "alice" // 用户
obj := "data1" // 资源
act := "read" // 操作

allowed, _ := e.Enforce(sub, obj, act)

if allowed {
fmt.Println("允许访问")
} else {
fmt.Println("拒绝访问")
}
}

执行结果:

1
允许访问

5. Casbin 进阶用法

(1) 使用 RBAC

model.conf(RBAC)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[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

policy.csv

1
2
3
p, admin, data1, read
p, admin, data1, write
g, alice, admin

Alice 拥有 admin 的权限。


(2) 动态策略存储(MySQL)

Casbin 支持把策略存数据库,而不是写在 CSV 文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import (
_ "github.com/go-sql-driver/mysql"
"github.com/casbin/casbin/v2"
"github.com/casbin/xorm-adapter/v3"
)

func main() {
// 连接 MySQL
a, _ := xormadapter.NewAdapter("mysql", "root:123456@tcp(127.0.0.1:3306)/")

// 使用数据库做存储
e, _ := casbin.NewEnforcer("model.conf", a)

// 加载策略
e.LoadPolicy()

// 添加策略
e.AddPolicy("bob", "data2", "write")
e.SavePolicy()
}

(3) 集成 Gin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import (
"github.com/casbin/casbin/v2"
"github.com/gin-gonic/gin"
)

func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")

r := gin.Default()
r.Use(func(c *gin.Context) {
sub := c.GetHeader("user") // 从请求头获取用户
obj := c.Request.URL.Path // 请求路径
act := c.Request.Method // 请求方法

ok, _ := e.Enforce(sub, obj, act)
if !ok {
c.JSON(403, gin.H{"error": "forbidden"})
c.Abort()
return
}
c.Next()
})

r.GET("/data1", func(c *gin.Context) {
c.JSON(200, gin.H{"msg": "success"})
})

r.Run(":8080")
}

6. 学习 Casbin 要掌握的知识点

  1. 基本概念:Model / Policy / Enforcer
  2. 常见模型:ACL / RBAC / ABAC
  3. 模型配置文件(.conf)的语法
  4. 策略存储方式:文件、数据库、Redis 等
  5. Enforce API 用法
  6. 集成 Web 框架(Gin / Echo / gRPC)
  7. 高级功能
    • 动态加载策略
    • 多租户权限
    • RESTful 风格的路径匹配
    • 缓存加速(casbin/casbinx)

常用 API Demo

下面给出一个 Go 单文件 Demo,展示 Casbin 常用 API 的实际调用,并打印结果,方便快速熟悉。


model.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[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

policy.csv

1
2
3
p, alice, data1, read
p, bob, data2, write
g, alice, admin

main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package main

import (
"fmt"

"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/util"
)

func main() {
e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
e.LoadPolicy()

// 1. Enforce 权限校验
fmt.Println("--- Enforce ---")
ok, _ := e.Enforce("alice", "data1", "read")
fmt.Println("alice read data1:", ok)
ok, _ = e.Enforce("bob", "data1", "read")
fmt.Println("bob read data1:", ok)

// 2. 查询策略
fmt.Println("--- GetPolicy ---")
fmt.Println(e.GetPolicy())

perms, _ := e.GetPermissionsForUser("alice")
fmt.Println("--- GetPermissionsForUser(alice) ---")
fmt.Println(perms)

roles, _ := e.GetRolesForUser("alice")
fmt.Println("--- GetRolesForUser(alice) ---")
fmt.Println(roles)

users, _ := e.GetUsersForRole("admin")
fmt.Println("--- GetUsersForRole(admin) ---")
fmt.Println(users)

// 3. 添加策略 / 角色关系
fmt.Println("--- AddPolicy ---")
e.AddPolicy("tom", "data3", "read")
fmt.Println(e.GetPolicy())

e.AddRoleForUser("bob", "admin")
roles, _ = e.GetRolesForUser("bob")
fmt.Println("--- AddRoleForUser ---")
fmt.Println("roles for bob:", roles)

// 4. 删除策略 / 角色关系
fmt.Println("--- RemovePolicy ---")
e.RemovePolicy("tom", "data3", "read")
fmt.Println(e.GetPolicy())

e.DeleteRoleForUser("bob", "admin")
roles, _ = e.GetRolesForUser("bob")
fmt.Println("--- DeleteRoleForUser ---")
fmt.Println("roles for bob:", roles)

// 5. 更新策略
fmt.Println("--- UpdatePolicy ---")
e.UpdatePolicy(
[]string{"alice", "data1", "read"},
[]string{"alice", "data1", "write"},
)
fmt.Println(e.GetPolicy())

// 6. 缓存 & 自定义函数
e.AddFunction("KeyMatch", util.KeyMatchFunc)
fmt.Println("--- Custom matcher (KeyMatch) ---")
ok, _ = e.Enforce("alice", "/data/123", "write")
fmt.Println("alice write /data/123:", ok)
}


运行结果示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
--- Enforce ---
alice read data1: true
bob read data1: false

--- GetPolicy ---
[[alice data1 read] [bob data2 write]]

--- GetPermissionsForUser(alice) ---
[[alice data1 read]]

--- GetRolesForUser(alice) ---
[admin]

--- GetUsersForRole(admin) ---
[alice]

--- AddPolicy ---
[[alice data1 read] [bob data2 write] [tom data3 read]]

--- AddRoleForUser ---
roles for bob: [admin]

--- RemovePolicy ---
[[alice data1 read] [bob data2 write]]

--- DeleteRoleForUser ---
roles for bob: []

--- UpdatePolicy ---
[[alice data1 write] [bob data2 write]]

--- Custom matcher (KeyMatch) ---
alice write /data/123: true

这个 Demo 涵盖了:

  1. 权限校验Enforce
  2. 策略查询GetPolicyGetPermissionsForUserGetRolesForUser
  3. 策略管理AddPolicyRemovePolicyUpdatePolicy
  4. 角色管理AddRoleForUserDeleteRoleForUser
  5. 自定义函数AddFunction(如 RESTful 路径匹配)
[up主专用,视频内嵌代码贴在这]