RBAC
角色定义
[role_definition]
用于定义 RBAC 角色继承关系。 Casbin 支持多个实例的 RBAC 系统,其中用户可以拥有角色及其继承关系,资源也可以拥有角色及其继承关系。 这两个 RBAC 系统不会相互干扰。
此部分为可选。 如果你在模型中不使用 RBAC 角色,那么省略此部分。
[role_definition]
g = _, _
g2 = _, _
上述角色定义显示 g
是一个 RBAC 系统,而 g2
是另一个 RBAC 系统。 ,表示在继承关系中涉及两个方。 在最常见的情况下,如果你只需要用户的角色,通常只使用
g。 当你需要用户和资源的角色(或组)时,也可以同时使用
g和
g2`。 请参阅 rbac_model.conf 和 rbac_model_with_resource_roles.conf 以获取示例。
Casbin 在策略中存储实际的用户-角色映射(如果你在资源上使用角色,则为资源-角色映射)。 例如:
p, data2_admin, data2, read
g, alice, data2_admin
这意味着 alice
继承/是角色 data2_admin
的成员。 在这里,alice
可以是用户,资源,或者角色。 Casbin 只将其识别为字符串。
然后,在匹配器中,你应该如下所示检查角色:
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
这意味着请求中的 sub
应该在策略中拥有角色 sub
。
- Casbin 只存储用户-角色映射。
- Casbin 不验证用户是否是有效用户或角色是否是有效角色。 这应由身份验证来处理。
- 不要在 RBAC 系统内为用户和角色使用相同的名称,因为 Casbin 将用户和角色识别为字符串,Casbin 无法知道你是指定用户
alice
还是角色alice
。 你可以简单地通过使用role_alice
来解决这个问题。 - 如果
A
有角色B
,并且B
有角色C
,那么A
有角色C
。 这种传递性目前是无限的。
按照惯例,策略定义中的主题令牌名称为 sub
并放在开头。 现在,Golang Casbin 支持自定义令牌名称和位置。 如果主题令牌名称是 sub
,则主题令牌可以放在任意位置,无需任何额外操作。 如果主题令牌名称不是 sub
,无论其位置如何,都应在初始化执行器后调用 e.SetFieldIndex()
为 constant.SubjectIndex
。
# `subject` here is for sub
[policy_definition]
p = obj, act, subject
e.SetFieldIndex("p", constant.SubjectIndex, 2) // index starts from 0
ok, err := e.DeleteUser("alice") // without SetFieldIndex, it will raise an error
角色层次结构
Casbin 的 RBAC 支持 RBAC1 的角色层次结构特性,这意味着如果 alice
有 role1
,并且 role1
有 role2
,那么 alice
也将拥有 role2
并继承其权限。
在这里,我们有一个叫做层次级别的概念。 所以,在这个例子中,层次级别是 2。 对于 Casbin 中的内置角色管理器,你可以指定最大层次级别。 默认值是 10。 这意味着像 alice
这样的最终用户只能继承 10 个级别的角色。
// NewRoleManager is the constructor for creating an instance of the
// default RoleManager implementation.
func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager {
rm := RoleManager{}
rm.allRoles = &sync.Map{}
rm.maxHierarchyLevel = maxHierarchyLevel
rm.hasPattern = false
return &rm
}
如何区分角色和用户?
Casbin 在其 RBAC 中并不区分角色和用户。 它们都被视为字符串。 如果你只使用单级 RBAC(其中角色永远不会是另一个角色的成员),你可以使用 e.GetAllSubjects()
获取所有用户和 e.GetAllRoles()
获取所有角色。 它们将分别列出所有 g, u, r
规则中的所有 u
和所有 r
。
但是,如果你正在使用多级 RBAC(具有角色层次结构)并且你的应用程序不记录名称(字符串)是用户还是角色,或者你有一个用户和一个角色具有相同的名称,你可以在将其传递给 Casbin 之前为角色添加前缀,如 role::admin
。 这样,你可以通过检查这个前缀来知道它是否是一个角色。
如何查询隐式角色或权限?
当用户通过 RBAC 层次结构继承角色或权限,而不是在策略规则中直接分配它们时,我们称这种类型的分配为“隐式”。 要查询此类隐式关系,你需要使用这两个 API:GetImplicitRolesForUser()
和 GetImplicitPermissionsForUser()
,而不是 GetRolesForUser()
和 GetPermissionsForUser()
。 有关更多详细信息,请参阅 此 GitHub 问题。
在 RBAC 中使用模式匹配
角色管理器
详见 Role Managers 部分。