Pular para o conteúdo principal

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), onde allow indica que a permissão é concedida, e deny indica que é negada.

Exemplos:

  • p, ROLE_ROOT, SystemMenu, read, allow significa que o papel ROLE_ROOT tem acesso de leitura ao item de menu SystemMenu.
  • p, ROLE_ROOT, UserMenu, read, deny significa que o papel ROLE_ROOT é negado o acesso de leitura ao item de menu UserMenu.

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ário user é atribuído ao papel ROLE_USER.
  • g, ROLE_ADMIN, ROLE_USER significa que ROLE_ADMIN herda permissões de ROLE_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 que UserSubMenu_allow é um submenu de UserMenu.
  • g2, (NULL), SystemMenu indica que SystemMenu 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_ADMINROLE_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.