基于角色的访问控制(RBAC)与上下文?

时间:2016-06-08 13:33:24

标签: php mysql codeigniter acl rbac

我正在尝试实施RBAC,但用户可以拥有多个角色,每个角色都在特定的上下文下。

上下文基于3个因素,CompanyProductRegion

因此,用户A可以是公司1的Admin,也可以是公司2的Viewer&gt; <产品3> 4区

这种RBAC设置的最佳方法是什么?

我正在努力推动这一点 - 所以寻找构建数据库表的最佳方法,以便进行这种级别的细粒度访问。

不幸的是,这是在运行PHP CodeIgniter / mySQL的遗留应用程序上 - 因此任何现有的现有库都可能不兼容。

更新

到目前为止,我有这个。 Permissions Roles表映射到Rolesaccount_id | role_id | company_id | product_id | region_id | ------------------------------------------------------------ 1 | 1 | | | | 2 | 2 | 1 | | | 2 | 3 | 2 | 1 | | 3 | 4 | 3 | 1 | 2 | 3 | 4 | 3 | 1 | 3 | 3 | 4 | 3 | 1 | 4 | 然后分配给用户和给定上下文。

SELECT DISTINCT account_id
FROM   user_roles ur, role_permissions rp
JOIN permissions p ON rp.permission_id=p.id

WHERE (
    #correct user that has a role with the permission we want
    ur.account_id = 1 
    AND rp.permission_id IN (1,2,3) 
    AND ur.role_id = rp.role_id

    #if the user is sys admin they can see everything
    AND (
        ur.role_id = 1

        #if the user is company admin
        OR (  ur.role_id = 2 AND ur.company_id=@cid )

        #if the user is product admin
        OR ( ur.role_id = 3 AND ur.company_id=@cid AND  ur.product_id=@pid )

        #if the user is any other role then the need explicit access
        OR ( ur.role_id > 3 AND ur.company_id=@cid AND ur.product_id=@pid AND ur.country_code=@cc )
    )

);

SQL for this看起来有点像......

boot.ts

这有效,但我确信必须有更好的方法来做到这一点。

下一个问题是如何将角色应用于角色?
那么公司的“管理员”&gt;产品&gt; region只能创建用户,他们的角色还是更低?

我必须在我们所处的环境中查找他们分配的角色,然后返回每个角色的级别低于用户的角色?

这个上下文可以更好地作为字符串放置吗? '1.3.gb'/'1.2'?然后在查找角色时,我首先形成上下文字符串?

1 个答案:

答案 0 :(得分:0)

用户表可以对滚动表进行交叉引用,每个卷都有一个特定的角色标识号,其中包含can_writecan_read列(等等...)

你的heircachy看起来像这样:

Users:
    uid(int) auto_increment primary
    role_id(int)

Roles:
    rid(int) auto_increment primary
    description(varchar)
    // any access values ie: can_read(int)

然后你可以设置一个子角色表,允许查看区域。

访问这些表的一些示例代码:

$stmp = (new PDO(...))->Prepare("SELECT role_id FROM Users WHERE uid = :userid");
$stmp->bindValue(":userid", $id); // I'd suggest storing a login key using sessions
$stmp->execute();
$user_permissions = $stmp->Fetch()['role_id'];

// Reference the Roles table for permission lists
$stmp = (new PDO(...))->Prepare("SELECT * FROM Roles WHERE rid = :roleid");
$stmp->bindValue(":roleid", $user_permissions);
[...]

希望这会有所帮助。