# Casbin 专注、高效的访问控制框架 ## 什么是casbin 几乎所有的系统在设计的时候都要有权限管理的模块,如果每次开发都要重新实现一次权限管理,光是想想就觉得无聊,程序员嘛能用轮子就用轮子,因此`casbin`出现了。 `casbin`是一个强大、高效的访问控制库。支持常用的多种访问控制模型,如`ACL/RBAC/ABAC`等。可以实现灵活的访问权限控制。同时,`casbin`支持多种编程语言,`Go/Java/Node/PHP/Python/.NET/Rust`。 ## casbin的特点 1. 支持自定义请求的格式,默认的请求格式为`{subject, object, action}`。 2. 具有访问控制模型model和策略policy两个核心概念。 3. 支持RBAC中的多层角色继承,不止主体可以有角色,资源也可以具有角色。 4. 支持超级用户,如 `root` 或 `Administrator`,超级用户可以不受授权策略的约束访问任意资源。 5. 支持多种内置的操作符,如 `keyMatch`,方便对路径式的资源进行管理,如 `/foo/bar` 可以映射到 `/foo*` ## 不是casbin该管的事 1. 身份认证 authentication(即验证用户的用户名、密码),casbin只负责访问控制。应该有其他专门的组件负责身份认证,然后由casbin进行访问控制,二者是相互配合的关系。 2. 管理用户列表或角色列表。 Casbin 认为由项目自身来管理用户、角色列表更为合适, 用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器。 而是存储RBAC方案中用户和角色之间的映射关系。 ## 常用授权模型 ### ACL `ACL`是`Access Control List`的缩写,称为访问控制列表. 定义了谁可以对某个数据进行何种操作. 关键数据模型有: 用户, 权限. ACL规则简单, 也带来一些问题: 资源的权限需要在用户间切换的成本极大; 用户数或资源的数量增长, 都会加剧规则维护成本; #### 典型应用 1. 文件系统 文件系统的文件或文件夹定义某个账号(user)或某个群组(group)对文件(夹)的读(read)/写(write)/执行(execute)权限. 1. 网络访问 防火墙: 服务器限制不允许指定机器访问其指定端口, 或允许特定指定服务器访问其指定几个端口. ### RBAC `RBAC`是`Role-based access control`的缩写, 称为 基于角色的访问控制. 核心数据模型有: 用户, 角色, 权限. 用户具有角色, 而角色具有权限, 从而表达用户具有权限. 由于有角色作为中间纽带, 当新增用户时, 只需要为用户赋予角色, 用户即获得角色所包含的所有权限. `RBAC`存在多个扩展版本, `RBAC0`、`RBAC1`、`RBAC2`、`RBAC3`。这些版本的详细说明可以参数[这里](https://www.jianshu.com/p/b078abe9534f)。我们在实际项目中经常使用的是`RBAC1`,即带有角色继承概念的RBAC模型。 ### ABAC `ABAC`是`Attribute-based access control`的缩写, 称为基于属性的访问控制. 权限和资源当时的状态(属性)有关, 属性的值可以用于正向判断(符合某种条件则通过), 也可以用于反向判断(符合某种条件则拒绝): #### 典型应用 1. 论坛的评论权限, 当帖子是锁定状态时, 则不再允许继续评论; 2. Github 私有仓库不允许其他人访问; 3. 发帖者可以编辑/删除评论(如果是RBAC, 会为发帖者定义一个角色, 但是每个帖子都要新增一条用户/发帖角色的记录); 4. 微信聊天消息超过2分钟则不再允许撤回; 5. 12306 只有实名认证后的账号才能购票; 6. 已过期的付费账号将不再允许使用付费功能; ## 实现一个简单的ACL授权验证模型 ### 安装 ``` go get github.com/casbin/casbin ``` ### 编写模型文件(Model.conf) 具体语法可以参考官方教程 [Model语法](https://casbin.org/docs/zh-CN/syntax-for-models) ``` [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)) ``` ### 编写策略文件(Policy.csv) ``` p, dajun, data1, read p, lizi, data2, write ``` 上述文件的具体意义如下 有一条`p(策略)`,定义了`dajun(sub), data1(obj), read(act)`,语义化就是`dajun`可以对`data1`执行`read`方法 ### code ```go 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](https://casbin.org) github地址:[go-casbin](https://github.com/casbin/casbin) 官方论坛:[forum.casbin.com](https://forum.casbin.com/) QQ 群:546057381( Casbin 访问控制讨论群) 社区为多个语言的多个框架适配了相应的中间件,未来将会有更多框架支持,如果你希望参与贡献,欢迎加入casbin社区 ## 参考 > https://cloud.tencent.com/developer/article/1534674 > > https://juejin.im/post/6844904191257739277