sql >> Base de Datos >  >> RDS >> Mysql

Cómo diseñar un sistema de control de acceso basado en roles jerárquicos

Hay una manera de implementar la herencia de roles usando una relación recursiva en la tabla Roles , al hacer una referencia de rol a otro registro:

Esta relación agregará 1 : n herencia dentro de Roles registro. 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 concedidos permisos con algo como esto:

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

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

Pero, en este caso, se necesitaba otro algoritmo de obtención de jerarquías.

Para resolver la anulación problema, tendrá que obtener permisos de rol y permisos de usuario. Luego, escribe user permisos sobre roles permisos para session .

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