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
), dondeallow
indica que se concede el permiso, ydeny
indica que se niega.
Ejemplos:
p, ROLE_ROOT, SystemMenu, read, allow
significa que el rolROLE_ROOT
tiene acceso de lectura al elemento del menúSystemMenu
.p, ROLE_ROOT, UserMenu, read, deny
significa que al rolROLE_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 usuariouser
está asignado al rolROLE_USER
.g, ROLE_ADMIN, ROLE_USER
significa queROLE_ADMIN
hereda permisos deROLE_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 queUserSubMenu_allow
es un submenú deUserMenu
.g2, (NULL), SystemMenu
indica queSystemMenu
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_ADMIN | ROLE_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.