Estou tentando entender a troca inerente entre funções e permissões quando se trata de controle de acesso (autorização).
Vamos começar com um dado: em nosso sistema, uma Permissão será uma unidade de acesso refinada (" Editar recurso X ", " Acessar a página do painel " etc.). Uma função será uma coleção de mais de 1 permissão. Um usuário pode ter 1 ou mais funções. Todos esses relacionamentos (usuários, funções, permissões) são todos armazenados em um banco de dados e podem ser alterados rapidamente e conforme necessário.
Minhas preocupações:
(1) O que há de tão "ruim" em verificar funções para controle de acesso? Quais são os benefícios obtidos pela verificação de permissões? Em outras palavras, qual é a diferença entre esses dois trechos abaixo:
if(SecurityUtils.hasRole(user)) {
// Grant them access to a feature
}
// vs.
if(SecurityUtils.hasPermission(user)) {
// Grant them access to a feature
}
E:
(2) Nesse cenário, que valor útil as Funções oferecem? Não poderíamos apenas atribuir mais de uma permissão aos usuários diretamente? Que valor concreto da abstração as Funções oferecem (alguém pode dar exemplos específicos)?
Respostas:
No momento da verificação, o código de chamada precisa apenas saber "o usuário X tem permissão para executar a ação Y?" .
O código de chamada não se importa e não deve estar ciente dos relacionamentos entre funções e permissões.
A camada de autorização verificará se o usuário tem essa permissão, geralmente verificando se a função do usuário tem essa permissão. Isso permite alterar a lógica de autorização sem atualizar o código de chamada.
Se você verificar diretamente a função no site de chamada, estará implicitamente criando relacionamentos de permissão de função e injetando lógica de autorização no código de chamada, violando a separação de preocupações.
Se você decidir posteriormente que a função
foo
não deve ter permissãobaz
, será necessário alterar todos os códigos que verificam se o usuário é umfoo
.As funções representam conceitualmente uma coleção nomeada de permissões.
Digamos que você esteja adicionando um novo recurso que permite ao usuário editar determinadas configurações. Esse recurso deve estar disponível apenas para administradores.
Se você estiver armazenando permissões por usuário, terá de encontrar todos os usuários do seu banco de dados que, de alguma forma, sejam administradores (se você não estiver armazenando informações de função para os usuários, como saberia quais usuários são administradores?) E acrescente essa permissão para sua lista de permissões.
Se você usar funções, precisará anexar a permissão à
Administrator
função, que é mais fácil de executar, mais eficiente em termos de espaço e menos propensa a erros.fonte
authorization layer
Provavelmente, nada significa mais do que simplesmente ter a definição da função (ie)user->hasPermission(SOME_PERMISSION)
verificar internamente primeiro as funções do usuário e depois verificar se alguma das funções inclui / exclui o dado permissão. Por exemplo,the calling code
pode estar verificando se uma determinada página está visível para o usuário e chamariauser->hasPermission(VIEW_GIVEN_PAGE)
, eauthorization layer
consiste na definição dahasPermission
função que verifica as funções como acima.hasPermission
pode verificarusersRole.HasPermission(VIEW_GIVEN_PAGE) && !user.Suspended
. O ponto é que tudo é feito em um só lugar e não no código de consumo (de chamada).Em resposta à sua primeira pergunta, o maior problema ao verificar se um usuário tem uma função e não uma permissão específica é que as permissões podem ser mantidas por várias funções. Como exemplo disso, um desenvolvedor pode ter acesso para ver o portal do desenvolvedor na intranet da empresa, que provavelmente também é uma permissão mantida por seu gerente. Se um usuário estiver tentando acessar o portal do desenvolvedor, você terá uma verificação semelhante a:
(Uma
switch
declaração no seu idioma de escolha seria melhor, mas ainda não particularmente organizada)Quanto mais comum ou amplamente realizada uma permissão, mais funções de usuário você precisa verificar para garantir que alguém possa acessar um determinado sistema. Isso também levaria ao problema de que toda vez que você modificar as permissões de uma função, será necessário modificar a verificação para refletir isso. Em um sistema grande, isso se tornaria muito difícil de manejar muito rapidamente.
Se você simplesmente verificar se o usuário tem a permissão que lhes permite acessar o portal do desenvolvedor, por exemplo, não importa qual a função que eles desempenham, eles terão acesso concedido.
Para responder à sua segunda pergunta, o motivo pelo qual você tem funções é que elas agem com a facilidade de modificar e distribuir "pacotes" de permissões. Se você possui um sistema com centenas de funções e milhares de permissões, a adição de um novo usuário (por exemplo, um novo gerente de RH) exigiria que você passasse e concedesse a ele todas as permissões que outros gerentes de RH possuem. Isso não seria apenas entediante, mas também propenso a erros se feito manualmente. Compare isso simplesmente adicionando a função "Gerente de RH" ao perfil de um usuário, o que concederá a eles o mesmo acesso que qualquer outro usuário com essa função.
Você pode argumentar que pode simplesmente clonar um usuário existente (se o seu sistema oferecer suporte a isso), mas, embora isso conceda ao usuário as permissões corretas para esse momento, tentar adicionar ou remover uma permissão para todos os usuários no futuro pode ser difícil. Um exemplo de cenário para isso é se, talvez no passado, a equipe de RH também estivesse encarregada da folha de pagamento, mas mais tarde a empresa se tornasse suficientemente grande para contratar pessoal especificamente para lidar com a folha de pagamento. Isso significa que o RH não precisa mais acessar o sistema de folha de pagamento, para que a permissão possa ser removida. Se você possui 10 membros diferentes de RH, precisará passar manualmente e remover a permissão correta, que introduz a possibilidade de erro do usuário. O outro problema com isso é que ele simplesmente não escala; À medida que você ganha mais e mais usuários em uma determinada função, torna muito mais difícil a modificação de uma função. Compare isso com o uso de funções, onde você precisaria modificar apenas a função abrangente em questão para remover a permissão, que seria refletida por todos os usuários que possuem essa função.
fonte