php mysql permissions hierarchy rbac

php - Cómo diseñar un sistema de control de acceso basado en funciones jerárquicas



mysql permissions (1)

Hay una forma de implementar la herencia de roles mediante el uso de relaciones recursivas en Table Roles , al hacer referencia de roles a otro registro:

Esta relación agregará 1 : n herencia dentro del registro de Roles . Puede obtener un árbol de jerarquía completo con esta función almacenada:

CREATE FUNCTION `getHierarchy`(`aRole` BIGINT UNSIGNED) RETURNS VARCHAR(1024) NOT DETERMINISTIC READS SQL DATA BEGIN DECLARE `aResult` VARCHAR(1024) DEFAULT NULL; DECLARE `aParent` BIGINT UNSIGNED; SET `aParent` = (SELECT `parent` FROM `Roles` WHERE `id` = `aRole`); WHILE NOT `aParent` IS NULL DO SET `aResult` = CONCAT_WS('','', `aResult`, `aParent`); SET `aParent` = (SELECT `parent` FROM `Roles` WHERE `id` = `aParent`); END WHILE; RETURN IFNULL(`aResult`, ''''); END

Entonces, puede obtener todos los permisos concedidos con algo como esto:

SELECT `permission_id` FROM `Permission_Role` WHERE FIND_IN_SET(`role_id`, `getHierarchy`({$role})) AND grant;

Si no es suficiente, entonces puede hacer otra tabla para la herencia:

Pero, en este caso, necesitó otro algoritmo de obtención de jerarquía.

Para resolver el problema de anulación , deberá obtener permisos de función y de usuario. Luego, escriba permisos de user sobre permisos de roles para la session .

Además, sugiero eliminar las columnas de grant en Permission_Role y Permission_User . No es necesario mapear todos los permisos para cada uno de ellos. Solo lo suficiente para usar las consultas EXISTS : si hay un registro, entonces se concede el permiso; de lo contrario, no es así. Si necesita recuperar todos los permisos y estados, puede usar LEFT JOIN s.

El trato básico es que tenemos un "kickstart" personalizado para nuestros proyectos. Para esto, estamos buscando rehacer el control del usuario. Sé que hay muchas preguntas sobre RBAc general, pero no puedo encontrar ninguna en el rbac jerárquico.

Nuestros requisitos son:

  • Los roles se pueden asignar a permisos de grupo
  • Si la función no tiene una entrada de permiso, se denegará automáticamente.
  • Un usuario puede recibir permisos de anulación
  • Los usuarios que anulan los permisos son una concesión o una denegación
  • Si a un usuario se le niega explícitamente un permiso, sin importar qué roles diga "concedido", prevalecerá la anulación.
  • Los usuarios pueden tener múltiples roles
  • Los roles pueden tener jerarquía
  • Los roles pueden heredar de otros roles (por ejemplo, un rol de "Foro Súper Moderador" es un "Moderador del Foro" y un "Mantenimiento del Sistema", y el rol del "Moderador del Foro" ya hereda de la función "Usuario del Foro")
  • Los roles que heredan de otro rol que deniega u otorga un privilegio anulan su permiso de hijo
  • Los permisos se agrupan por "módulo" (por ejemplo, un módulo "Blog" puede tener un permiso "editar entrada" y un módulo "Foro" puede tener un permiso de "entrada de edición" y no chocarán)
  • Hay un permiso "Todo y cualquier cosa" que otorga automáticamente acceso completo

Entonces, con esos requisitos fuera del camino, así es como estoy pensando en hacerlo.

Tabla: Usuarios

id | int | unique id

Tabla: Roles

id | int | unique id --------------|--------------------------------------------- title | varchar | human readable name

Tabla: Permisos

id | int | unique id --------------|--------------------------------------------- module | varchar | module name --------------|--------------------------------------------- title | varchar | human readable name --------------|--------------------------------------------- key | varchar | key name used in functions

Tabla: Role_User

role_id | int | id from roles table --------------|--------------------------------------------- user_id | int | id from users table

Tabla: Permission_Role

id | int | unique id --------------|--------------------------------------------- permission_id | int | id from permissions table --------------|--------------------------------------------- role_id | int | id from roles table --------------|--------------------------------------------- grant | tinyint | 0 = deny, 1 = grant

Tabla: Permiso_Usuario

id | int | unique id --------------|--------------------------------------------- permission_id | int | id from permissions table --------------|--------------------------------------------- user_id | int | id from users table --------------|--------------------------------------------- grant | tinyint | 0 = deny, 1 = grant

Bueno, en realidad eso es la mitad, estoy seguro de esa parte, la parte en la que me estoy estancando es en los roles jerárquicos.

Entonces, ¿cómo diseño esto? Mi idea es que para guardar las consultas de la base de datos, voy a construir la matriz de permisos al iniciar sesión y guardarla en la sesión para que las consultas no tengan que ser demasiado simples, ya que solo se ejecutan una vez para cada inicio de sesión.

El problema que veo es que voy a necesitar conocer la jerarquía de los roles para poder resolver los permisos de roles heredados antes de resolver la herencia.

Los permisos de usuario son la parte fácil, los permisos por usuario son esencialmente el grupo finalmente resuelto.