How to design a hierarchical role based access control system

后端 未结 1 1732
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-07 07:14

Basic deal is, we have a custom built \"kickstart\" for our projects. For this we are looking at redoing the user control. I know there are a lot of questions out there abou

相关标签:
1条回答
  • 2020-12-07 08:11

    There is a way to implement role inheritance by using recursive relation on table Roles, by making role reference to another record:

    1:n inheritance

    This relation will add 1 : n inheritance within Roles record. You might obtain whole hierarchy tree with this stored function:

    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
    

    Then, you might obtain all granted permissions with something like this:

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

    If it's not enough, then you might do another table for inheritance:

    n:m inheritance

    But, in this case, needed another hierarchy obtainment algorithm.


    To resolve overriding issue you will have to get role permissions and user permissions. Then, write user permissions over roles permissions to session.


    Also, I suggest to remove grant columns in Permission_Role and Permission_User. There is no need to map every permission for each of them. Just enough to use EXISTS queries: if there is a record, then permission granted, else - it's not. If you need to retrieve all permissions and statuses, you might use LEFT JOINs.

    0 讨论(0)
提交回复
热议问题