RBAC
Definição de Papel
A [role_definition]
é usada para definir as relações de herança de papéis no RBAC. O Casbin suporta múltiplas instâncias de sistemas RBAC, onde usuários podem ter papéis e suas relações de herança, e recursos também podem ter papéis e suas relações de herança. Esses dois sistemas RBAC não interferirão um com o outro.
Esta seção é opcional. Se você não usa papéis RBAC no modelo, então omita esta seção.
[role_definition]
g = _, _
g2 = _, _
A definição de papel acima mostra que g
é um sistema RBAC, e g2
é outro sistema RBAC. _,_
significa que há duas partes envolvidas em uma relação de herança. No caso mais comum, você geralmente usa g
sozinho se você só precisa de papéis para usuários. Você também pode usar tanto g
quanto g2
quando você precisa de papéis (ou grupos) tanto para usuários quanto para recursos. Por favor, veja os exemplos em rbac_model.conf e rbac_model_with_resource_roles.conf.
O Casbin armazena o mapeamento real entre usuário-papel (ou mapeamento recurso-papel se você está usando papéis em recursos) na política. Por exemplo:
p, data2_admin, data2, read
g, alice, data2_admin
Isso significa que alice
herda/é membro do papel data2_admin
. Aqui, alice
pode ser um usuário, um recurso ou um papel. O Casbin apenas o reconhece como uma string.
Então, em um comparador, você deve verificar o papel como mostrado abaixo:
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
Isso significa que o sub
na solicitação deve ter o papel sub
na política.
- O Casbin apenas armazena o mapeamento usuário-papel.
- O Casbin não verifica se um usuário é um usuário válido ou se um papel é um papel válido. Isso deve ser cuidado pela autenticação.
- Não use o mesmo nome para um usuário e um papel dentro de um sistema RBAC, porque o Casbin reconhece usuários e papéis como strings, e não há como o Casbin saber se você está especificando o usuário
alice
ou o papelalice
. Você pode simplesmente resolver isso usandorole_alice
. - Se
A
tem o papelB
, eB
tem o papelC
, entãoA
tem o papelC
. Esta transitividade é infinita por enquanto.
Convencionalmente, o nome do token de sujeito na definição de política é sub
e colocado no início. Agora, o Casbin em Golang suporta nomes de tokens personalizados e seus lugares. Se o nome do token de sujeito é sub
, o token de sujeito pode ser colocado em um lugar arbitrário sem nenhuma ação extra necessária. Se o nome do token de sujeito não é sub
, e.SetFieldIndex()
para constant.SubjectIndex
deve ser chamado após o inicializador do executor, independentemente de sua posição.
# `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
Hierarquia de Papéis
O RBAC do Casbin suporta a característica de hierarquia de papéis do RBAC1, o que significa que se alice
tem role1
, e role1
tem role2
, então alice
também terá role2
e herdará suas permissões.
Aqui, temos um conceito chamado nível de hierarquia. Então, neste exemplo, o nível de hierarquia é 2. Para o gerenciador de papéis embutido no Casbin, você pode especificar o nível máximo de hierarquia. O valor padrão é 10. Isso significa que um usuário final como alice
só pode herdar 10 níveis de papéis.
// 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
}
Como Distinguir Papel de Usuário?
O Casbin não distingue entre papéis e usuários em seu RBAC. Ambos são tratados como strings. Se você usa apenas um RBAC de nível único (onde um papel nunca será membro de outro papel), você pode usar e.GetAllSubjects()
para obter todos os usuários e e.GetAllRoles()
para obter todos os papéis. Eles listarão todos os u
e todos os r
, respectivamente, em todas as regras g, u, r
.
Mas se você está usando um RBAC de múltiplos níveis (com hierarquia de papéis) e sua aplicação não registra se um nome (string) é um usuário ou um papel, ou você tem um usuário e um papel com o mesmo nome, você pode adicionar um prefixo ao papel como role::admin
antes de passá-lo para o Casbin. Dessa forma, você saberá se é um papel verificando este prefixo.
Como Consultar Papéis ou Permissões Implícitas?
Quando um usuário herda um papel ou permissão via hierarquia RBAC em vez de ser diretamente atribuído a eles em uma regra de política, chamamos esse tipo de atribuição de 'implícita'. Para consultar tais relações implícitas, você precisa usar estas duas APIs: GetImplicitRolesForUser()
e GetImplicitPermissionsForUser()
em vez de GetRolesForUser()
e GetPermissionsForUser()
. Para mais detalhes, por favor, veja esta questão no GitHub.
Usando Correspondência de Padrões no RBAC
Veja RBAC com Padrão
Gerenciador de Funções
Veja a seção Gerenciadores de Funções para detalhes.