1. casbin 是什么
开源的访问控制库,支持多种访问控制模型
- 支持自定义访问控制语法
- 管理访问控制模型及策略的存储
- 支持RBAC 的角色关系映射
- 内置超级用户
- 内置多种规则匹配算子
- 访问控制不是账户验证,casbin不提供密码验证功能
- casbin也不会存储任何用户信息(如角色、密码等)
2. casbin hello world
2.1. 创建一个casbin执行器实例:
e, err := casbin.NewEnforcer(model, adapter)
需要两个参数,第一个是访问控制模型,第二个是适配器(supported-adapters)
- 默认模式,传入模型文件和文件适配器(用户权限配置):
e, err := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")
- 传入符合格式的模型字符串和数据库适配器:
a, err := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/casbin")
m, err := model.NewModelFromString(`
[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
`)
e, err := casbin.NewEnforcer(m, a)
也可以用gorm来适配数据库:adapter, err := gormadapter.NewAdapterByDB(db)
2.2. 检查权限
ok, err := e.Enforce(sub, obj, act)
, 把这里类比成语言中的主谓宾就很好理解了
sub := "alice" // the user that wants to access a resource.
obj := "data1" // the resource that is going to be accessed.
act := "read" // the operation that the user performs on the resource.
ok, err := e.Enforce(sub, obj, act)
if err != nil {
// handle err
}
if ok == true {
// permit alice to read data1
} else {
// deny the request, show an error
}
- 批量检查
results, err := e.BatchEnforce([][]interface{}{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"jack", "data3", "read"}})
返回一个布尔切片,其中 results[0] 为{"alice", "data1", "read"}
的权限检查结果,以此类推。 - casbin 也提供运行时的权限管理接口
roles, err := e.GetRolesForUser("alice")
Management API
3. 模型文件的格式
model.conf
文件包含以下4个部分:Policy, Effect, Request, Matchers
3.1 request
定义请求参数及其顺序, 最少需要主谓宾三个, 比如刚刚的r = sub, obj, act
3.2 policy
- policy definition
提供了访问策略的定义,比如有如下策略定义:
[policy_definition]
p = sub, obj, act
p2 = sub, act
而实际策略(policy.csv)为:
p, alice, data1, read
p2, bob, write-all-objects
通过p和p2,策略定义为实际策略中的多条记录提供了匹配机制:
(alice, data1, read) -> (p.sub, p.obj, p.act)
(bob, write-all-objects) -> (p2.sub, p2.act)
- policy effect
策略生效规则,定义了当一个请求符合多个策略时,应该如何提供访问权限,是对Matchers的匹配结果再次进行逻辑组合判断的模型。 比如:
[policy_effect]
e = some(where (p.eft == allow))
其中,p.eft
是策略最终生效的结果,即同意allow
或不同意deny
,以上定义的意思是,只要有任一条策略同意,则最终生效结果为同意。
e = some (where (p.eft == allow)) && !some(where (p.eft == deny)
有符合允许结果的策略,并且,无符合拒绝结果的策略,则结果为真
实际上目前casbin只提供了预定义的5个policy effect:policy-effect
3.3 Matcher
定义了request 和 policy的匹配规则。
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
最简单的匹配,表示request 和policy中的主谓宾应该一致
matcher 布尔语法文档: https://github.com/Knetic/govaluate/blob/master/MANUAL.md
matcher 函数文档: https://casbin.org/docs/en/function
3.4 例子
ACL model:
[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:
p, alice, data1, read
p, bob, data2, write
意思是,alice可以读data1,bob可以写data2
3.5 RBAC 和ABAC的区别
- 基于角色的访问控制 (Role-based access control)
- 基于属性的访问控制(Attribute-based access control - ABAC)使用 ABAC 鉴权