你好开发者。授权是我们构建的每个系统的关键部分,而 Casbin 是我们在每种语言中听到的授权的通用名称。

Casbin 目前支持 Golang、Java、C/C++、Node.js、Javascript、PHP、Laravel、Python、.NET (C#)、Delphi、Rust、Ruby、Swift (Objective-C)、Lua (OpenResty)、 Dart(Flutter)和 Elixir。

在本文中,我的目标是以简单易懂的流程演示 casbin 的工作原理及其不同的可用模型配置。

Casbin的工作流程

在进行不同的模型配置之前,让我们尝试通过一个简单的概览图来理解 casbin 的工作流程,如下所示。

我已将整个工作流程分为两个阶段,即配置实施

配置阶段

这个阶段是关于配置的。

第一步(模型)

在这里,我们根据我们的要求配置模型。我们使用CONF文件(.conf 文件扩展名)来抽象我们的模型配置。此配置基于 PERM 元模型(Policy、Effect、Request、Matchers)(将在下面通过示例进行详细说明)。

在上图中,我取了Casbin中最基本最简单的模型即ACL(后面会讲到)

Step2(政策)

who can do whatwho has what permissions

政策的基本语法是

p= sub, obj, act, eft

此语法可以理解为 who( sub ) can/cannot( allow / deny ) do what( act ) on some resource( obj )

eftallowdenyallow

在上图中,根据定义的策略

  1. John 有权读取 RECORD1

  2. John 没有写入 RECORD1 的权限

  3. Harry 有权读取 RECORD1

  4. Harry 有权写入 RECORD1

实施阶段

此阶段是关于根据模型配置[第 1 步] 和列出的策略 [第 2 步] 实施

Step3(请求)

这是用户尝试访问某些资源或对其执行所需操作的实时场景。

在上图中,根据传入请求

  1. 约翰想读 RECORD1

  2. 约翰想在 RECORD1 上写

执行结果

这是在决定是否允许用户访问给定资源或对给定资源执行他想要的操作时的实时场景。

Step4(匹配器)

执行结果的第一步是将请求与策略列表相匹配。在上面的示例中,我们有以下匹配器表达式,它只是保证请求中的主题、对象和操作应该与策略规则中的相匹配。

m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

Step5(政策效果)

使用匹配器表达式从策略列表中找到策略后,执行结果的另一个步骤是应用策略效果。在上面的示例中,我们有以下策略效果,这意味着用户只要有一个匹配的策略允许他这样做就具有权限

e = some(where (p.eft == allow))

在这两个步骤之后,casbin 执行结果为

  1. John 可以阅读 RECORD1 ✔️

  2. John 被拒绝在 RECORD1 上写文章 ❌

更深入

我希望上面的简单概述能在一定程度上帮助可视化 Casbin 的工作流程。现在我们将看到配置模型的不同方法[根据上图的第 1 步]

访问控制的类型

访问控制列表 (ACL)

这是最基本的访问控制机制。这列出了每个用户对给定资源的权限的 1–1 映射。

If there are total three users;user1,user2,user3. There is a permissions defined for each users individually.user1 can only read record1user2 can only write record1user3 can read and write record1

Casbin模型配置

# 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
r = sub, obj, actp = sub, obj, act

政策效应

e = some(where (p.eft == allow))

其他一些变化

e = !some(where (p.eft == deny))e = some(where (p.eft == allow)) && !some(where (p.eft == deny))

匹配器

m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

基于角色的访问控制 (RBAC)

这解决了之前需要的上述 1-1 映射。现在我们将用户分配到角色中,并将权限分配给角色而不是单个用户。

If there are total three users;user1,user2,user3 and two role;admin and user. In this case we define permission to the role not to the individual user.user1,user2 has role useruser3 has role adminuser can only read record1 (user1,user2)admin can read and write write record1 (user3)

Casbin模型配置

[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
g
g = _, _
// user1 is a admin and admin can write record1 which means user1 can write record1p, admin, record1, writeg, user1, admin

具有资源角色的 RBAC

就像我们将用户分组到角色中一样,我们也可以将资源分组并分配它们,而不是一次分配一个资源。

[request_definition]r = sub, obj, act
[policy_definition]p = sub, obj, act
[role_definition]g = _, _g2 = _, _
[policy_effect]e = some(where (p.eft == allow))
[matchers]m = g(r.sub, p.sub) && g2(r.obj, p.obj) && r.act == p.act
g2
g2 = _, _
// record1 and record2 is grouped to record and user1 can write record which means user1 can write record1 and record2 bothp, user1, record, writeg2, record1, recordg2, record2, record

带域的 RBAC(租户)

这是 RBAC 的另一个版本,当系统中有多个租户并且用户在不同的租户中具有不同的角色时,它可能是必不可少的。

[request_definition]r = sub, dom, obj, act
[policy_definition]p = sub, dom, obj, act
[role_definition]g = _, _, _
[policy_effect]e = some(where (p.eft == allow))
[matchers]m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
//user1 is admin in tenant1 and user2 is admin in tenant2. Admin in tenant1(which means user1) can read and write data1. Similarly Admin in tenant2(which means user2) can read and write data2. This also means user1 has no permission to read/write data2 and viceversa.p, admin, tenant1, data1, readp, admin, tenant1, data1, writep, admin, tenant2, data2, readp, admin, tenant2, data2, writeg, user1, admin, tenant1g, user2, admin, tenant2

基于属性的访问控制 (ABAC)

如果您的用例无法通过上述任何模型解决,还有另一种模型可以提供更精细的搜索/匹配器。评估是基于特定属性(如用户属性)完成的。在 casbin 的情况下,属性可以是主题、对象或操作的属性。

例如,RBAC 系统向所有经理授予访问权限,但 ABAC 策略将仅向财务部门的经理授予访问权限

[request_definition]r = sub, obj, act
[policy_definition]p = sub, obj, act
[policy_effect]e = some(where (p.eft == allow))
[matchers]m = r.sub == r.obj.Owner

此模态配置仅检查请求的用户是否是该请求对象的所有者。

//If Following Requestuser1, {Owner:"user1"}user1, {Owner:"user2"}//Mapping the request to sub,obj,actsub= user1obj= {Owner:"user1"}//Matchers we haver.sub == r.obj.Owneruser1 == user1 // 1st Request is given accessuser1 == user2 // 2nd Request is not given access as he is not the owner of that resource

同样,还有更多模型可用于不同的用例。我的目标是让您开始使用 casbin。现在我希望您可以继续通过本文档学习更深入的知识,或者在casbin 在线编辑器中练习模型和策略。

结论

对casbin的理解就到此为止了。我们将在下一篇文章中继续这段从理解 casbin 到在 golang 中实现 casbin 的旅程。希望这篇文章对我的读者有所帮助。任何类型的建议都将不胜感激。快乐编码。

如果你喜欢我的文章,点赞,关注,转发!