Casbin入门
Casbin 是一个强大和高效的开放源码访问控制库,它支持各种 访问控制模型 以强制全面执行授权。
在 Casbin 中, 访问控制模型被抽象为基于 PERM (Policy, Effect, Request, Matcher) 的一个配置文件
-
R 请求
-
P 策略
-
E 影响
-
M 匹配
Casbin 在线编辑器 https://casbin.org/zh/editor
R请求定义 [Request_Definition]
[request_definition]
r = sub, obj, act
- Sub 访问实体(对象/主角)
- Obj 访问的资源
- act 访问的动作
这些 Sub Obj Act 可以理解为函数的形参!,当请求的时候传入具体的参数,比如下面的案例!
张三, 李四, 杀掉
[表示,张三 对 李四 执行 杀掉的动作!]
下一步就是定义策略!
策略(具体的政策) [policy_definition]
[policy_definition]
p = sub, obj, act
同样的!用一些参数来表示:
- Sub 访问实体(对象/主角)
- Obj 访问的资源
- act 访问的动作
然后我们需要自定在策略文件中根据定义来定义具体的策略
p, 张三, 李四, 杀掉
p, 王五, 赵六, 诈骗
策略分别定义了
- 张三 对 李四 执行 杀掉的动作!
- 王五 对 赵六 执行 诈骗的动作!
匹配规则/判决规则 [matchers]
当有了请求和策略!下一步就是定义规则!
一开始我不理解,为什么有了策略还需要规则!毕竟策略定义好了之后!根据策略好像也能去判断!
比如传进来的是 p, 张三, 李四, 杀掉 政策里面有 p, 张三, 李四, 杀掉 那就说明匹配上了!
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
如果我们想设计的是一个违法条例,里面标记了一些人物 目标 和行为!在不同的国家不同的地区可能判决的方式不同!所以规则就不同!
所以我们还需要单独建立一套规则!来确定政策和请求的合理性!
可以看到我们上面制定的政策都是一些违法的政策!
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
然后这个 matchers 只返回两个结果 allow(代表当前的请求,在这个规则中是匹配成功了违法的政策,allow 允许你去吃牢饭)/deny(则反之,不允许你进去蹭牢房!)
影响结果 effect (判决书!)
通过上面我们的一些请求!我们自己定义的一些政策,然后根据规则来确定政策的执行规则!然后这些执行都会有一个影响结果!!
[policy_effect]
e = some(where (p.eft == allow))
如果有返回allow的代表影响是符合上面的违法政策,代表违法了的!可以去吃牢饭!!
策略(具体的政策)的第四个参数 eft (effect)
我们可以给政策多去传入一个effect~ (allow,deny)
其实本身是有默认值的,
allow
,我们上面定义的违法行为(满足规则的)默认都可以去吃牢饭!
[policy_definition]
p = sub, obj, act, eft
这样的话我们可以更灵活的指定我们的政策,比如上面的我们只能指定一些违法的政策在里面,有了这个,我们可以同时制定合法的和违法的,只要去后面跟上这个effect
影响结果的参数就可以了!
p, 张三, 李四, 杀掉
p, 王五, 赵六, 诈骗
+ p, 刘大脑袋,宋小宝,请吃饭,deny
比如我们在之前的基础上,给法律政策上增加了一条 p, 刘大脑袋,宋小宝,请吃饭,deny
因为我们本身定义的政策是基于违法政策改变的
加入了一个合法政策,那么这个合法政策的影响就是不违法的,所以影响 effect
就是deny
[判决你不能去蹭牢饭!]
其他的不变,那么当我们的请求是 刘大脑袋,宋小宝,请吃饭
的审判结果为 false
!不触犯我们的违法政策!
关于结果的审判方式Policy effect
https://casbin.org/zh/docs/syntax-for-models#policy-effect定义
目前的审判方式呢~ 是用硬解码写死在源码中的!目前为止你必须使用内置的 policy effects,不能自定义。
支持的 policy effects 如下:
Policy effect定义 | 意义 | 示例 | |
---|---|---|---|
some(where (p.eft == allow)) | allow-override | ACL, RBAC, etc. | 有一个为allow就返回true |
!some(where (p.eft == deny)) | deny-override | 拒绝改写 | 有一个为deny则返回false,否则返回true |
some(where (p.eft == allow)) && !some(where (p.eft == deny)) | allow-and-deny | 同意与拒绝 | 有一个为allow且没有deny则返回true,否则返回false |
priority(p.eft) || deny | priority | 优先级 | 返回策略中第一个匹配到的eft,否则就false |
subjectPriority(p.eft) | 基于角色的优先级 | 主题优先级 | - |
如何选择你的审判方式和你的政策规则都有关系!
比如我们在之前的基础上增加一条 p, 刘大脑袋,宋小宝,请吃饭,allow
,
p, 张三, 李四, 杀掉
p, 王五, 赵六, 诈骗
p, 刘大脑袋,宋小宝,请吃饭,deny
+ p, 刘大脑袋,宋小宝,请吃饭,allow
当审判方式的不同,能不能吃上牢饭就是另一回事了!
Request | 审判方式Policy effect | 审判结果 |
---|---|---|
刘大脑袋,宋小宝,请吃饭 | e = some(where (p.eft == allow)) | True 吃的上牢饭 |
刘大脑袋,宋小宝,请吃饭 | e = !some(where (p.eft == deny)) | False 吃不上牢饭 |
刘大脑袋,宋小宝,请吃饭 | e = some(where (p.eft == allow)) && !some(where (p.eft == deny)) | False 吃不上牢饭 |
priority(p.eft) || deny
需要换个顺序分别测试
p, 张三, 李四, 杀掉
p, 王五, 赵六, 诈骗
p, 刘大脑袋,宋小宝,请吃饭,allow
p, 刘大脑袋,宋小宝,请吃饭,deny
priority(p.eft)
会优先匹配到 刘大脑袋,宋小宝,请吃饭,allow
然后根据规则审判,把Request和Policy 放入规则,如果规则匹配成功则返回 对应的eft
这里优先拿 p, 刘大脑袋,宋小宝,请吃饭,allow
去对比规则,成功返回 allow 那么 priority(p.eft)
为 allow 判决结果为true 可以吃牢饭!
如果把策略的后两个换个位置!
p, 张三, 李四, 杀掉
p, 王五, 赵六, 诈骗
p, 刘大脑袋,宋小宝,请吃饭,deny
p, 刘大脑袋,宋小宝,请吃饭,allow
这个如果规则上后,根据规则先返回的deny
! priority(p.eft)
就是deny 那么判决就是false了!
还有一个
subjectPriority(p.eft)
这个放到后面学习!
评论区