Ir al contenido principal

Menu Permissions

Comenzamos presentando un ejemplo de Spring Boot que presenta un sistema de menú. Este ejemplo aprovecha jCasbin para gestionar los permisos del menú. En última instancia, tiene como objetivo abstraer un middleware, específicamente para permisos de menú, que podría extenderse a otros lenguajes soportados por Casbin, como Go y Python.

1. Archivos de Configuración

Necesitas configurar la gestión de roles y permisos en el archivo policy.csv, junto con las relaciones padre-hijo entre los elementos del menú. Para más detalles, por favor consulta este repositorio de GitHub.

1.1 Visión General

Usando policy.csv, puedes configurar de manera flexible los permisos de rol y las estructuras de menú para un control de acceso detallado. Este archivo de configuración define los permisos de acceso para diferentes roles en varios elementos del menú, asociaciones entre usuarios y roles, y las relaciones jerárquicas entre los elementos del menú.

1.2 Definiciones de Permisos (Políticas)

  • Reglas de Política: Las políticas se definen con un prefijo p, especificando roles (sub) y sus permisos (act) en elementos del menú (obj), junto con el efecto de la regla (eft), donde allow indica que se concede el permiso, y deny indica que se niega.

Ejemplos:

  • p, ROLE_ROOT, SystemMenu, read, allow significa que el rol ROLE_ROOT tiene acceso de lectura al elemento del menú SystemMenu.
  • p, ROLE_ROOT, UserMenu, read, deny significa que al rol ROLE_ROOT se le niega el acceso de lectura al elemento del menú UserMenu.

1.3 Roles y Asociaciones de Usuarios

  • Herencia de Roles: Las relaciones usuario-rol y las jerarquías de roles se definen con un prefijo g. Esto permite a los usuarios heredar permisos de uno o varios roles.

Ejemplos:

  • g, user, ROLE_USER significa que el usuario user está asignado al rol ROLE_USER.
  • g, ROLE_ADMIN, ROLE_USER significa que ROLE_ADMIN hereda permisos de ROLE_USER.

1.4 Jerarquía de Elementos del Menú

  • Relaciones del Menú: Las relaciones padre-hijo entre elementos del menú se definen con un prefijo g2, ayudando en la construcción de la estructura de un menú.

Ejemplos:

  • g2, UserSubMenu_allow, UserMenu indica que UserSubMenu_allow es un submenú de UserMenu.
  • g2, (NULL), SystemMenu indica que SystemMenu no tiene un elemento de submenú, lo que significa que es un elemento de menú de nivel superior.

1.5 Herencia de Permisos del Menú y Reglas Predeterminadas

Al gestionar permisos de menú con jCasbin, la relación de permisos entre menús padres e hijos sigue reglas de herencia específicas, con dos reglas predeterminadas importantes:

Herencia de Permisos del Menú Padre: Si a un menú padre se le concede explícitamente el permiso allow, todos sus submenús también tienen por defecto el permiso allow a menos que se marque específicamente como deny.

Esto significa que una vez que un menú padre es accesible, sus submenús también son accesibles por defecto. Manejo de Menús Padres Sin Configuraciones de Permiso Directas: Si un menú padre no tiene configuraciones de permiso directas (ni explícitamente permitidas ni denegadas) pero tiene al menos un submenú con permiso allow concedido explícitamente, entonces se considera implícitamente que el menú padre tiene permiso allow.

Esto asegura que los usuarios puedan navegar a estos submenús.

1.6 Reglas Especiales de Herencia de Permisos En cuanto a la herencia de permisos entre roles, especialmente en escenarios que involucran permisos de deny, se deben seguir las siguientes reglas para asegurar la seguridad del sistema y un control preciso de los permisos:

Distinción Entre Negaciones Explícitas y Predeterminadas: Si a un rol, como ROLE_ADMIN, se le niega explícitamente el acceso a un elemento del menú, como AdminSubMenu_deny (marcado como deny), entonces incluso si este rol es heredado por otro rol (por ejemplo, ROLE_ROOT), el rol heredero no tiene permiso de acceso al elemento del menú denegado.

Esto asegura que las políticas de seguridad explícitas no se eludan debido a la herencia de roles.

Herencia de Permisos de Negación Predeterminada: Por el contrario, si la negación de acceso de un rol a un elemento del menú (por ejemplo, UserSubMenu_deny) es predeterminada (no marcada explícitamente como deny, sino porque no se le concedió explícitamente allow), entonces cuando este rol es heredado por otro rol (por ejemplo, ROLE_ADMIN), el rol heredero puede anular el estado de deny predeterminado, permitiendo el acceso a estos elementos del menú.

1.7 Descripción del Ejemplo política:

NombreDelMenú

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. Control de Permiso de Menú

La lista de todos los elementos del menú accesibles por un nombre de usuario dado se puede identificar a través de la función findAccessibleMenus() disponible en MenuService. Para verificar si un usuario específico tiene los derechos para acceder a un elemento de menú designado, se puede utilizar el método checkMenuAccess(). Este enfoque asegura que los permisos de menú se controlen efectivamente, aprovechando las capacidades de jCasbin para gestionar los derechos de acceso de manera eficiente.