Understanding How Casbin Matching Works in Detail
Neste post, vou explicar o design e a implementação do RBAC usando a biblioteca Casbin. Para uma plataforma SaaS lidando com múltiplas hierarquias de recursos e papéis que herdam permissões de níveis superiores, Casbin oferece uma alternativa performática a ser considerada.
Introdução ao RBAC
RBAC é um método de restringir o acesso a recursos com base nos papéis que os indivíduos possuem. Para entender melhor como o RBAC hierárquico funciona, vamos dar uma olhada no sistema RBAC do Azure na próxima seção e depois tentar implementar um sistema semelhante.
Entendendo o RBAC Hierárquico do Azure
Há um papel chamado Owner para todos os recursos no Azure. Suponha que se eu tenho o papel de Owner atribuído a mim no nível de assinatura, isso significa que sou o Owner de todos os grupos de recursos e recursos sob essa assinatura. Se eu tenho o papel de Owner no nível do grupo de recursos, então sou o Owner de todos os recursos sob esse grupo de recursos.
Esta imagem mostra que tenho acesso de Owner no nível da assinatura.
Quando verifico o IAM de um Grupo de Recursos sob esta Assinatura, você pode ver que herdei o acesso de Owner da assinatura.
Então, é assim que o RBAC do Azure é hierárquico. A maioria dos softwares empresariais usa RBAC hierárquico devido à natureza hierárquica dos níveis de recursos. Neste tutorial, tentaremos implementar um sistema semelhante usando Casbin.
Como Funciona o Casbin?
Antes de mergulhar na implementação, é importante entender o que é Casbin e como ele funciona em um alto nível. Este entendimento é necessário porque cada sistema de Controle de Acesso Baseado em Papéis (RBAC) pode variar com base em requisitos específicos. Ao compreender o funcionamento do Casbin, podemos ajustar eficazmente o modelo.
O que é ACL?
ACL significa Lista de Controle de Acesso. É um método no qual os usuários são mapeados para ações e ações para recursos.
A definição do modelo
Vamos considerar um exemplo simples de um modelo ACL.
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
A request_definition é o template de consulta do sistema. Por exemplo, uma solicitação
alice, write, data1
pode ser interpretada como 'A sujeito Alice pode realizar a ação 'write' no objeto 'data1'?'A policy_definition é o template de atribuição do sistema. Por exemplo, ao criar uma política
alice, write, data1
, você está atribuindo permissão ao sujeito Alice para realizar a ação 'write' no objeto 'data1'.O policy_effect define o efeito da política.
Na seção matchers, a solicitação é combinada com a política usando as condições
r.sub == p.sub && r.obj == p.obj && r.act == p.act
.
Agora vamos testar o modelo no editor Casbin
Abra o editor e cole o modelo acima no editor de Modelo.
Cole o seguinte no editor de Política:
p, alice, read, data1
p, bob, write, data2
e o seguinte no editor de Solicitação:
alice, read, data1
O resultado será:
true
Representação visual do modelo ACL, política e correspondência de solicitação
O que é RBAC?
RBAC significa Controle de Acesso Baseado em Papéis. No RBAC, um usuário é atribuído a um papel para um recurso, e um papel pode conter ações arbitrárias. A solicitação verifica então se o usuário tem permissão para realizar a ação no recurso.
A definição do modelo
Vamos considerar um exemplo simples de modelo RBAC:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && r.obj == p.obj
- A role_definition é um construtor de relação de gráfico que usa um Grafo para comparar o objeto de solicitação com o objeto de política.
Agora vamos testar o modelo no editor Casbin
Abra o editor e cole o modelo acima no editor de Modelo.
Cole o seguinte no editor de Política:
p, alice, reader, data1
p, bob, owner, data2
g, reader, read
g, owner, read
g, owner, write
e o seguinte no editor de Requisições:
alice, read, data1
alice, write, data1
bob, write, data2
bob, read, data2
bob, write, data1
O resultado será:
true
false
true
true
false
Representação visual do modelo RBAC, política e correspondência de requisições
A tabela g - Mapeamento de função para ação tem um mapeamento gráfico da função para ação. Este Gráfico pode ser codificado como uma lista de arestas, conforme mostrado na política, que é uma maneira comum de representar um Gráfico:
g, reader, read
g, owner, read
g, owner, write
p indica uma política normal que pode ser comparada usando o operador ==. g é uma função de comparação baseada em Gráfico. Você pode definir vários comparadores de Gráfico adicionando um sufixo numérico como g, g2, g3, ... e assim por diante.
O que é RBAC Hierárquico?
No RBAC Hierárquico, existem mais de um tipo de recursos e há uma relação de herança entre os tipos de recursos. Por exemplo, "assinatura" é um tipo e "grupoDeRecursos" é outro tipo. Uma sub1 do tipo Assinatura pode conter vários gruposDeRecursos (rg1, rg2) do tipo GrupoDeRecursos.
Semelhante à hierarquia de recursos, haverá dois tipos de funções e ações: funções e ações de Assinatura, e funções e ações de GrupoDeRecursos. Há uma relação arbitrária entre a função de Assinatura e a função de GrupoDeRecursos. Por exemplo, considere uma Função de Assinatura proprietário-sub. Esta função é herdada por uma Função de GrupoDeRecursos proprietário-rg, o que significa que se eu for atribuído à função proprietário-sub na Assinatura sub1, então eu automaticamente também obtenho a função proprietário-rg em rg1 e rg2.
A definição do modelo
Vamos pegar um exemplo simples do modelo RBAC Hierárquico:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && g2(p.obj, r.obj)
- O role_definition é um construtor de relação gráfica que usa um Gráfico para comparar o objeto de requisição com o objeto de política.
Agora vamos testar o modelo no editor Casbin
Abra o editor e cole o modelo acima no editor de Modelo.
Cole o seguinte no editor de Política:
p, alice, sub-reader, sub1
p, bob, rg-owner, rg2
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
E cole o seguinte no editor de Requisições:
alice, rg-read, rg1
O resultado será:
true
Representação visual do modelo RBAC, política e correspondência de requisições
A tabela g - Mapeamento de função para (Ação, Função) tem um gráfico mapeando a função para a ação, mapeamento de função. Este gráfico pode ser codificado como uma lista de arestas, conforme mostrado na política, que é uma maneira comum de representar um gráfico:
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
A tabela g2 - Mapeamento de Assinatura para GrupoDeRecursos tem um gráfico mapeando assinatura para grupoDeRecursos:
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
Representação visual da correspondência de Sujeito
Representação visual da correspondência de Ação
Representação visual da correspondência de Objeto
Quando uma requisição é submetida ao Casbin, essa correspondência acontece para todas as políticas. Se pelo menos uma política corresponder, então o resultado da requisição é verdadeiro. Se nenhuma política corresponder à requisição, então o resultado é falso.
Conclusão
Neste tutorial, aprendemos sobre como diferentes modelos de autorização funcionam e como eles podem ser modelados usando Casbin. Na segunda parte deste tutorial, implementaremos isso em uma aplicação de demonstração Spring Boot e protegeremos as APIs usando Casbin.