几乎所有的系统在设计的时候都要有权限管理的模块,如果每次开发都要重新实现一次权限管理,光是想想就觉得无聊,程序员嘛能用轮子就用轮子,因此casbin
出现了。
casbin
是一个强大、高效的访问控制库。支持常用的多种访问控制模型,如ACL/RBAC/ABAC
等。可以实现灵活的访问权限控制。同时,casbin
支持多种编程语言,Go/Java/Node/PHP/Python/.NET/Rust
。
{subject, object, action}
。root
或 Administrator
,超级用户可以不受授权策略的约束访问任意资源。keyMatch
,方便对路径式的资源进行管理,如 /foo/bar
可以映射到 /foo*
ACL
是Access Control List
的缩写,称为访问控制列表. 定义了谁可以对某个数据进行何种操作. 关键数据模型有: 用户, 权限.
ACL 规则简单, 也带来一些问题: 资源的权限需要在用户间切换的成本极大; 用户数或资源的数量增长, 都会加剧规则维护成本;
文件系统的文件或文件夹定义某个账号(user)或某个群组(group)对文件(夹)的读(read)/写(write)/执行(execute)权限.
防火墙: 服务器限制不允许指定机器访问其指定端口, 或允许特定指定服务器访问其指定几个端口.
RBAC
是Role-based access control
的缩写, 称为 基于角色的访问控制. 核心数据模型有: 用户, 角色, 权限.
用户具有角色, 而角色具有权限, 从而表达用户具有权限.
由于有角色作为中间纽带, 当新增用户时, 只需要为用户赋予角色, 用户即获得角色所包含的所有权限.
RBAC
存在多个扩展版本, RBAC0
、RBAC1
、RBAC2
、RBAC3
。这些版本的详细说明可以参数这里。我们在实际项目中经常使用的是RBAC1
,即带有角色继承概念的 RBAC 模型。
ABAC
是Attribute-based access control
的缩写, 称为基于属性的访问控制.
权限和资源当时的状态(属性)有关, 属性的值可以用于正向判断(符合某种条件则通过), 也可以用于反向判断(符合某种条件则拒绝):
go get github.com/casbin/casbin
具体语法可以参考官方教程 Model 语法
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
[policy_effect]
e = some(where (p.eft == allow))
p, dajun, data1, read
p, lizi, data2, write
上述文件的具体意义如下
有一条p(策略)
,定义了dajun(sub), data1(obj), read(act)
,语义化就是dajun
可以对data1
执行read
方法
package main
import (
"fmt"
"log"
"github.com/casbin/casbin/v2"
)
func check(e *casbin.Enforcer, sub, obj, act string) {
ok, _ := e.Enforce(sub, obj, act)
if ok {
fmt.Printf("%s CAN %s %s\n", sub, act, obj)
} else {
fmt.Printf("%s CANNOT %s %s\n", sub, act, obj)
}
}
func main() {
e, err := casbin.NewEnforcer("./model.conf", "./policy.csv")
if err != nil {
log.Fatalf("NewEnforecer failed:%v\n", err)
}
check(e, "dajun", "data1", "read")
check(e, "lizi", "data2", "write")
check(e, "dajun", "data1", "write")
check(e, "dajun", "data2", "read")
}
至此一个简单的 ACL 模型的 demo 就完成了
官方网站:casbin.org
github 地址:go-casbin
官方论坛:forum.casbin.com
QQ 群:546057381 ( Casbin 访问控制讨论群)
社区为多个语言的多个框架适配了相应的中间件,未来将会有更多框架支持,如果你希望参与贡献,欢迎加入 casbin 社区