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.

34
demandé sur Hailwood 2013-04-22 08:59:47

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:

1:n inheritance

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:

n:m inheritance

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.

45
répondu BlitZ 2013-04-22 07:41:51