Comment concevoir un système de contrôle d'accès hiérarchique basé sur les rôles
accord de Base est que nous avons une coutume construit "kickstart" pour nos projets. Pour ce faire, nous envisageons de réorganiser le contrôle de l'utilisateur. Je sais qu'il y a beaucoup de questions sur le général rbac, mais je ne trouve aucune sur hiérarchique rbac?
nos exigences sont:
- Rôles peuvent être attribués à des autorisations de groupe
- si le rôle n'a pas de permission, il est automatiquement refusé
- on peut donner à un utilisateur une priorité absolue les autorisations
- un utilisateur outrepassant les permissions est soit une grant ou un deny
- si un utilisateur se voit refuser explicitement une permission, peu importe les rôles qui disent "accordé", la clause de dérogation l'emporte.
- les Utilisateurs peuvent avoir plusieurs rôles
- Rôles peut avoir de hiérarchie
- Rôles ne peut hériter que d'autres rôles (par exemple, Un "Forum Super Modérateur" rôle "Modérateur du Forum", et un "Système de Responsable", et le "Modérateur du Forum" rôle déjà hérite de la "Utilisateur du Forum" rôle )
- les rôles hérités d'un autre rôle qui nie ou accorde un privilège l'emportent sur la permission de leur enfant
- les Permissions sont groupées par "module" (par exemple un module" Blog "peut avoir une permission" editer entry", et un module" Forum "peut avoir une permission" editer entry " et ils ne se heurteront pas)
- il y a une permission" tout et N'importe quoi " qui accorde automatiquement un accès complet
Donc, avec ces exigences de le chemin, voici comment je pense à le faire.
Table: Les Utilisateurs
id | int | unique id
Table: Les Rôles
id | int | unique id
--------------|---------------------------------------------
title | varchar | human readable name
Table: Permissions
id | int | unique id
--------------|---------------------------------------------
module | varchar | module name
--------------|---------------------------------------------
title | varchar | human readable name
--------------|---------------------------------------------
key | varchar | key name used in functions
Table: Role_User
role_id | int | id from roles table
--------------|---------------------------------------------
user_id | int | id from users table
Table: 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
Table: Permission_User
id | int | unique id
--------------|---------------------------------------------
permission_id | int | id from permissions table
--------------|---------------------------------------------
user_id | int | id from users table
--------------|---------------------------------------------
grant | tinyint | 0 = deny, 1 = grant
Eh bien, en fait c'est la moitié, cette partie dont je suis sûr, la partie sur laquelle je suis coincé est les rôles hiérarchiques.
alors, comment puis-je la conception de cette? Mon idée est que pour sauvegarder les requêtes de la base de données, je vais juste construire la matrice de permission sur login et la sauvegarder en session pour que les requêtes ne soient pas trop simples car elles ne sont lancées qu'une fois pour chaque login.
la question que je vois est que, je vais avoir besoin de connaître la hiérarchie des rôles pour que je puisse résoudre les permissions héritées des rôles avant de résoudre l'héritage.
les permissions de l'utilisateur est la partie facile, les permissions de l'utilisateur sont essentiellement le groupe finalement résolu.
1 réponses
il y a une façon de mettre en œuvre l'héritage de rôle en utilisant la relation récursive sur la table Roles
, en faisant référence à un autre enregistrement:
cette relation ajoutera 1 : n
héritage à l'intérieur de Roles
enregistrement. Vous pouvez obtenir toute l'arborescence de la hiérarchie avec cette fonction stockée:
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
alors, vous pourriez obtenir tout accordées autorisations avec quelque chose comme ceci:
SELECT
`permission_id`
FROM
`Permission_Role`
WHERE
FIND_IN_SET(`role_id`, `getHierarchy`({$role}))
AND
grant;
Si ce n'est pas assez, alors vous pourriez faire une autre table pour l'héritage:
mais, dans ce cas, il fallait un autre algorithme d'obtention de la hiérarchie.
Pour résoudre prépondérant question vous devrez obtenir les permissions de rôle et les permissions d'utilisateur. Ensuite, écrire user
permissions sur roles
permissions session
.
aussi, je suggère de supprimer grant
colonnes dans Permission_Role
et Permission_User
. Il n'est pas nécessaire d' carte chaque autorisation pour chacun d'eux. Juste assez pour utiliser EXISTS
requêtes: si il y a un enregistrement, puis l'autorisation accordée, d'autre - il n'est pas. Si vous avez besoin de récupérer toutes les autorisations et les statuts, vous pouvez utiliser LEFT JOIN
S.