Pular para o conteúdo principal

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.

nota
  1. O Casbin apenas armazena o mapeamento usuário-papel.
  2. 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.
  3. 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 papel alice. Você pode simplesmente resolver isso usando role_alice.
  4. Se A tem o papel B, e B tem o papel C, então A tem o papel C. Esta transitividade é infinita por enquanto.
Convenção de Nomes de Tokens

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.