RBAC 和 Casbin 的关系?

RBAC大家都知道是一种访问控制模型,Casbin实现了这个模型,并且还实现了其他很多种访问控制模型,如ABAC模型。

Casbin 解决了什么问题?

无需自己从零开始做一套访问控制系统,比如为用户添加角色,为角色添加权限等等接口都已经实现了。这套框架被多种语言实现,并且有多种存储适配器。

Casbin 中的概念和 RBAC 的对应关系?

RBAC中的概念很简单,很容易理解,这里再赘述一下:角色,用户,权限。这三者组合来判断是否能形成对某一资源拥有访问资格。

Casbin中的概念虽然比较多(因为这一套框架还要兼容其他的访问控制模型),但是仔细看下去,也是比较容易理解的。

以张三读取文章接口为例

RBAC的鉴权流程:先看张三的所有身份,再看这些身份下是否拥有读取文章接口的权限。

Casbin的鉴权流程:将张三读取文章接口,抽取三个要素。

第一,操作对象(sub):张三

第二,动作(act):读取

第三,资源(obj):文章接口

将这三要素组合成一组请求r,拿着这组请求和已有的策略p,去某个列表里按某种匹配规则m进行匹配,匹配后的结果传入到影响 e中,看是否通过。(别急,下面有解释)。

以上涉及到了几个 Casbin 的重要概念,subactobjrpme。其中sub可以是单用户,也可以是角色。其中pme,相对于RBAC模型中我们可能很少遇到。

下面将对以上概念进行解释。

r:请求,由上述三要素组成,格式与p一致。可以理解为入口函数。

p:策略={sub,obj,act},会有一个策略列表(可以简单地理解为等同于 RBAC 中角色和权限的关系表)。通常我们如果仅用RBAC的话,理解到这里就可以了,后面其实还可以有一个参数,可以简单地理解为禁用(即该操作对象不能操作此资源),黑名单,表示这一组策略被拉黑或者通过,默认为通过。

m:m解决的是pr如何进行匹配的问题,是匹配规则,仅返回是否匹配中 。可以理解为如何找到策略列表中对应的规则。
比如在此项中,我们可以加入超级管理员的角色的匹配规则,即使没有匹配中常规规则,但如果你是超级管理员的话,也默认为匹配中了。

e:影响。仅做最终对匹配结果后的处理,即最终由这里返回是否通过。只可能有四种(官网有)。可以理解为最后的判断规则。为什么会有这个呢?按道理来说仅有m就够了啊?

实际上还是因为上面说过的原因,因为Casbin做的不仅是简单RBAC,在其他或者更高阶的RBAC中,可能会出现有一条策略匹配中了,同时也还匹配上了另外一条策略,但是后一条策略表达的是该用户不能使用此资源,问题就来了,一条允许,一条不允许,那到底是通不通过呢?这时e就发挥了作用,你既可以在此项设定所有策略都通过即为通过,也可以设定为有一条通过即为通过。

没有涉及到的概念:角色域。g=用户,角色。这个是用于多租户(多商户)模型的权限控制系统,这里不表。

其他概念和我的经验?

先简单了解一下,做的过程中大致流程和概念及要注意的点,这些清楚后我们就只是调用接口的事了。

两个文件

Casbin 官网中可以看到,初始化时,涉及到了两个文件,一个是模型配置文件model.conf,一个是策略文件。

模型文件中,可以定制上述概念的各种组合,比如说m中的超级管理员,e中的到底通不通过问题,别担心,这个或许真的不用存到数据库中,一般定下来就不会动了的。

策略文件,我们就还是算了吧,存储到数据库中,更方便我们管理,Casbin中有各种存储适配器,我使用的是grom的适配器。

注意点

  1. 在官网中,Casbin明确指出,用户表和角色表,应当由项目自己管理,Casbin只做权限控制。
  2. 当我们使用grom适配器时,初始化Casbin的时候,会默认创建一张表casbin_rules,这里面可以存储用户和角色的关系,角色和权限的关系。(这里只说使用CasbinRBAC模型)
  3. 上两点可以得知,用户表,角色表,权限表,我们无论从业务角度还是Casbin的限制,都应该我们自己来创建管理。
  4. 官方文档中,会存在一些错误,有时候我们还是需要读一下Casbin和适配器的源码,究竟该如何使用这些接口,甚至说看这些接口有没有。一定要注意Casbin和适配器的版本,不然可能跟文档对不上。
  5. Casbin为了性能考虑,会将一些数据载入内存中。所以,当项目重启时,一定要记得将casbin_rules那张表载入到内存中去,即初始化Casbin时,调用LoadPolicy()
  6. 在我们删除或修改用户,角色,权限时,记得想一下,casbin_rules那张表需不需要动呢?如果要动,可以去官网文档中找到对应接口。
  7. 我的实践,在casbin_rules中,角色和用户,我均只存储角色 id 和用户 id ,角色和权限的对应关系中,角色我存 id,权限通常是路由地址,因为检查权限通常是读多写少,这样做的好处是请求来时可以直接通过路由地址和用户 id 检验权限,不用自己再到数据库中查到路由地址 id 后再去查权限。

具体代码什么的很简单,就是纯调用接口。在这里我就不贴出来了,相信看到这里,再结合看一下Casbin文档,大家都能写出来。以上是我最近学习使用 Casbin的经验教训和总结,希望对大家有帮助。