Mysql
 sql >> Database >  >> RDS >> Mysql

Come progettare un sistema di controllo accessi basato su ruoli gerarchici

C'è un modo per implementare l'ereditarietà dei ruoli usando la relazione ricorsiva sulla tabella Roles , facendo riferimento al ruolo a un altro record:

Questa relazione aggiungerà 1 : n ereditarietà all'interno di Roles disco. Potresti ottenere l'intero albero della gerarchia con questa funzione memorizzata:

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

Quindi, potresti ottenere tutti i concessi autorizzazioni con qualcosa del genere:

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

Se non è abbastanza, potresti creare un'altra tabella per l'ereditarietà:

Ma, in questo caso, era necessario un altro algoritmo di ottenimento della gerarchia.

Per risolvere la sovrascrittura problema dovrai ottenere le autorizzazioni del ruolo e le autorizzazioni dell'utente. Quindi, scrivi user autorizzazioni su roles autorizzazioni per session .

Inoltre, suggerisco di rimuovere grant colonne in Permission_Role e Permission_User . Non è necessario mappa ogni permesso per ciascuno di essi. Quanto basta per usare EXISTS query:se c'è un record, l'autorizzazione è concessa, altrimenti non lo è. Se devi recuperare tutte le autorizzazioni e gli stati, puoi utilizzare LEFT JOIN s.