学习 casbin 的最大拦路虎就是他的两个配置文件,很多新手完全是蒙圈的。
这里我们以本地化权限控制为例,不直接上数据库化的,便于大家调试理解。
我们在使用 casbin 时需要用到两个配置文件,分别是 model.conf 和 policy.csv。
他们分别记录了,权限匹配规则也叫模型定义文件 model.conf ,以及权限列表也叫策略文件 policy.csv。
一、模型定义文件 model.conf
- [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
简单解释下这些定义的意义:
[request_definition]
这是关于请求的一些定义,分别定义了:
访问实体 (Subject),访问资源 (Object) 和访问方法 (Action)
这个很好理解:我们一般描述一条请求大都会这么描述:
哪个用户用啥方法请求了某个资源
这里的:
哪个用户→就是 实体 (Subject)
啥方法→就是 访问方法 (Action)
某个资源 → 访问资源 (Object)
比如:admin 用户使用 GET 方法访问 /user/list 接口
[policy_definition]
这是是对策略的定义。
我们还有一个配置文件 policy.csv ,这里就是约束里面定义些什么字段。
我们一般描述一个权限是这样的:
谁拥有对某个资源的啥权限
这里的:
谁→就是 实体 (Subject)
啥权限→就是 访问方法 (Action)
某个资源 → 访问资源 (Object)
比如:admin 组拥有 /user/list 接口的 GET 权限
[policy_effect]
这是对策略的定义。
我们在 request_definition 和 policy_definition 定义的这些资源,怎么去匹配。
不同的需求可以写成不同的方式,这里我们写成 RBAC 权限控制的经典方案:
- e = some(where (p.eft == allow))
p.eft 代表决策结果。
其意思就是:如果存在一个匹配的策略规则就通过。
[role_definition]
这是角色的定义。
_, _ 表示角色继承关系的前项和后项,即前项继承后项角色的权限。
就像 编辑 权限只有对文章的读写权限,管理员拥有 编辑 的全部权限,这种继承关系。
[matchers]
请求和策略的匹配规则。
先来解释下:
- r.obj == p.obj && r.act == p.act
这段就是在匹配的时候,请求传过来的 obj 和 我们策略组里面的 obj 要匹配到,同样是 act 也是同样。
最后来解释:
- g(r.sub, p.sub)
g 所关联的是角色定义,所以他要满足我们的前项继承后项角色的权限。
二、策略文件 policy.csv
- p, member, /depts, GET
- p, member, /depts/:id, GET
- p, admin, /depts, POST
- p, admin, /depts/:id, PUT
- p, admin, /depts/:id, DELETE
- g, admin, member
- g, super, admin
- g, lili, member
一看到 .csv 文件,就应该能想到,他是一种特殊的文件,我们很多从数据库里面导出数据就会导出这个格式的文件。
所以这部分的内容后期也可以从数据库里面去读取。
这个文件很好理解,结合上一个模型文件:
p 是定义资源的策略的
简而言之:谁拥有对某个资源的啥权限
g 是定义权限组的
简而言之:谁继承谁的权限