Menu Permissions
Iniciamos apresentando um exemplo de Spring Boot que apresenta um sistema de menu. Este exemplo utiliza o jCasbin para gerenciar permissões de menu. Em última análise, visa abstrair um middleware, especificamente para permissões de menu, que poderia ser estendido para outras linguagens suportadas pelo Casbin, como Go e Python.
1. Arquivos de Configuração
Você precisa configurar a gestão de papéis e permissões no arquivo policy.csv
, juntamente com as relações de parentesco entre os itens do menu. Para mais detalhes, por favor, consulte este repositório do GitHub.
1.1 Visão Geral
Usando policy.csv
, você pode configurar de forma flexível as permissões de papéis e as estruturas de menu para um controle de acesso granular. Este arquivo de configuração define permissões de acesso para diferentes papéis em vários itens de menu, associações entre usuários e papéis, e as relações hierárquicas entre os itens de menu.
1.2 Definições de Permissões (Políticas)
- Regras de Política: As políticas são definidas com um prefixo
p
, especificando papéis (sub
) e suas permissões (act
) em itens de menu (obj
), juntamente com o efeito da regra (eft
), ondeallow
indica que a permissão é concedida, edeny
indica que é negada.
Exemplos:
p, ROLE_ROOT, SystemMenu, read, allow
significa que o papelROLE_ROOT
tem acesso de leitura ao item de menuSystemMenu
.p, ROLE_ROOT, UserMenu, read, deny
significa que o papelROLE_ROOT
é negado o acesso de leitura ao item de menuUserMenu
.
1.3 Papéis e Associações de Usuários
- Herança de Papéis: Relacionamentos de usuário-papel e hierarquias de papéis são definidos com um prefixo
g
. Isto permite que os usuários herdem permissões de um ou vários papéis.
Exemplos:
g, user, ROLE_USER
significa que o usuáriouser
é atribuído ao papelROLE_USER
.g, ROLE_ADMIN, ROLE_USER
significa queROLE_ADMIN
herda permissões deROLE_USER
.
1.4 Hierarquia de Itens de Menu
- Relacionamentos de Menu: Relacionamentos de parentesco entre itens de menu são definidos com um prefixo
g2
, auxiliando na construção da estrutura de um menu.
Exemplos:
g2, UserSubMenu_allow, UserMenu
indica queUserSubMenu_allow
é um submenu deUserMenu
.g2, (NULL), SystemMenu
indica queSystemMenu
não tem um item de submenu, significando que é um item de menu de nível superior.
1.5 Herança de Permissões de Menu e Regras Padrão
Ao gerenciar permissões de menu com jCasbin, a relação de permissão entre menus pai e filhos segue regras específicas de herança, com duas regras padrão importantes:
Herança de Permissões do Menu Pai: Se um menu pai é explicitamente concedido a permissão allow
, todos os seus submenus também são padrão para a permissão allow
, a menos que especificamente marcados como deny
.
Isto significa que uma vez que um menu pai é acessível, seus submenus também são acessíveis por padrão. Tratamento de Menus Pais Sem Configurações de Permissão Diretas: Se um menu pai não tem configurações de permissão diretas (nem explicitamente permitidas nem negadas) mas tem pelo menos um submenu explicitamente concedido a permissão allow
, então o menu pai é implicitamente considerado como tendo permissão allow
.
Isto garante que os usuários possam navegar para esses submenus.
1.6 Regras Especiais de Herança de Permissões No que diz respeito à herança de permissões entre papéis, especialmente em cenários envolvendo permissões deny
, as seguintes regras devem ser seguidas para garantir a segurança do sistema e o controle preciso das permissões:
Distinção Entre Negações Explícitas e Padrão: Se um papel, como ROLE_ADMIN
, é explicitamente negado acesso a um item de menu, como AdminSubMenu_deny
(marcado como deny
), então mesmo que este papel seja herdado por outro papel (por exemplo, ROLE_ROOT
), o papel herdeiro não é permitido acesso ao item de menu negado.
Isto garante que políticas de segurança explícitas não sejam contornadas devido à herança de papéis.
Herança de Permissões de Negação Padrão: Por outro lado, se a negação de acesso de um papel a um item de menu (por exemplo, UserSubMenu_deny
) é padrão (não marcada explicitamente como deny
, mas porque não foi explicitamente concedida allow
), então quando este papel é herdado por outro papel (por exemplo, ROLE_ADMIN
), o papel herdeiro pode substituir o status de deny
padrão, permitindo acesso a esses itens de menu.
1.7 Descrição do Exemplo política:
NomeDoMenu
ROLE_ROOT
ROLE_ADMIN
ROLE_USER
p, ROLE_ROOT, SystemMenu, read, allow
p, ROLE_ROOT, AdminMenu, read, allow
p, ROLE_ROOT, UserMenu, read, deny
p, ROLE_ADMIN, UserMenu, read, allow
p, ROLE_ADMIN, AdminMenu, read, allow
p, ROLE_ADMIN, AdminSubMenu_deny, read, deny
p, ROLE_USER, UserSubMenu_allow, read, allow
g, user, ROLE_USER
g, admin, ROLE_ADMIN
g, root, ROLE_ROOT
g, ROLE_ADMIN, ROLE_USER
g2, UserSubMenu_allow, UserMenu
g2, UserSubMenu_deny, UserMenu
g2, UserSubSubMenu, UserSubMenu_allow
g2, AdminSubMenu_allow, AdminMenu
g2, AdminSubMenu_deny, AdminMenu
g2, (NULL), SystemMenu
✅ | ❌ | ROLE_ADMIN | ROLE_USER |
---|---|---|---|
SystemMenu | ✅ | ❌ | ❌ |
UserMenu | ❌ | ✅ | ❌ |
UserSubMenu_allow | ❌ | ✅ | ✅ |
UserSubSubMenu | ❌ | ✅ | ✅ |
UserSubMenu_deny | ❌ | ✅ | ❌ |
AdminMenu | ✅ | ✅ | ❌ |
AdminSubMenu_allow | ✅ | ✅ | ❌ |
AdminSubMenu_deny | ✅ | ❌ | ❌ |
2. Controle de Permissão de Menu
A lista de todos os itens de menu acessíveis por um determinado nome de usuário pode ser identificada através da função findAccessibleMenus()
disponível no MenuService. Para verificar se um usuário específico tem direitos de acesso a um item de menu designado, o método checkMenuAccess()
pode ser utilizado. Esta abordagem garante que as permissões de menu sejam efetivamente controladas, aproveitando as capacidades do jCasbin para gerenciar direitos de acesso de forma eficiente.