用 Django 用的多了,再用其他语言或框架会有点吃力,因为 Django 是保姆级别的,基本上 Web 开发你能遇到的问题,都有现成的解决方案,拿来就用即可。比如说权限管理,甚至数据库里面的表都给你设计好了。如果没有 Django,比如说你用了 Flask,或者 FastAPI,那该怎么做权限管理?
你可能会说自己建立角色表、权限表,角色和权限的映射表,再为用户配置角色,为角色配置权限,最后在视图函数或拦截器上编写判断逻辑。
没错,基本是这样,但是实现起来非常麻烦,有没有比较简单又高效的方案呢?有,那就是 Casbin。
Casbin 是什么
Casbin 是一个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型。GitHub 有 11.1 k 的星。
Casbin 还是一个通用的框架,支持主流的编程语言:
Casbin 可以做:
- 支持自定义请求的格式,默认的请求格式为 {subject, object, action}。
- 具有访问控制模型 model 和策略 policy 两个核心概念。
- 支持 RBAC 中的多层角色继承,不止主体可以有角色,资源也可以具有角色。
- 支持内置的超级用户 例如:root 或 administrator。超级用户可以执行任何操作而无需显式的权限声明。
- 支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo*
Casbin 不能:
- 身份认证 authentication(即验证用户的用户名和密码),Casbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 Casbin 进行访问控制,二者是相互配合的关系。
- 管理用户列表或角色列表。Casbin 认为由项目自身来管理用户、角色列表更为合适, 用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器,而是存储 RBAC 方案中用户和角色之间的映射关系。
Casbin 如何工作
在 Casbin 中, 访问控制模型被抽象为基于 PERM (Policy, Effect, Request, Matcher) 的一个文件。因此,切换或升级项目的授权机制与修改配置一样简单。
举个例子吧,编写这样一个模型配置文件 model.conf:
代码语言:javascript复制# Request definition
[request_definition]
r = sub, obj, act
# Policy definition
[policy_definition]
p = sub, obj, act
# Policy effect
[policy_effect]
e = some(where (p.eft == allow))
# Matchers
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
你说 sub、obj、act 是啥?其实是抽象出来的东西,你可以这么理解:把 sub 当作用户角色,把 obj 当作资源对象,比如说 api 的路径,act 当作行为,比如说 get 或 post 请求。
这个模型配置文件就表示当请求的 sub,obj,act 等于策略中的 sub,obj,act 的时候就放行,否则拒绝。
现在来编写策略文件:policy.csv
代码语言:javascript复制p, root, /api/users/confirm, GET
p, admin, /api/users/confirm, GET
这个策略就表示如果 sub 是 root 或者 admin 的时候,就可以对 /api/users/confirm 执行 GET 请求。
然后在请求拦截器加上这样的判断逻辑:
代码语言:javascript复制import casbin
e = casbin.Enforcer("path/to/model.conf", "path/to/policy.csv")
def 拦截器(*args **kwargs)
sub = "admin" # 这里写死,实际上从 request 对象获取用户角色
obj = "/api/users/confirm" # 实际上从 request 对象获取 URI
act = "GET" # 实际上从 request 对象中获取请求方法
if e.enforce(sub, obj, act):
print("放行")
...
else:
print("拒绝")
...
就这,只需在拦截器加上一小段逻辑,对原有代码基本没有入侵,使用起来是不是非常简单?
策略的配置即可放在文件中,也可以放在数据库中,做到更为灵活的配置。
安装
代码语言:javascript复制pip install casbin
最后的话
casbin 还有很多高级的功能,这里说的只是最简单的一种,官方文档[1]也有非常丰富的例子:
我也正在学习 casbin,分享给需要的朋友们。如有问题,留言交流。
参考资料
[1]官方文档: https://casbin.org/docs/zh-CN/get-started