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

Posted

技术标签:

【中文标题】基于角色的访问控制 (RBAC) 与上下文?【英文标题】:Role Based Access Controls (RBAC) with context? 【发布时间】:2016-10-08 19:29:00 【问题描述】:

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

上下文基于 3 个因素,CompanyProductRegion

所以用户 A 可以是公司 1 的 Admin,也可以是公司 2 > 产品 3 > 地区 4 的 Viewer

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

我目前正在手动进行此操作 - 因此正在寻找构建数据库表的最佳方法,以允许这种级别的细粒度访问。

不幸的是,这是在运行 php CodeIgniter / mysql 的遗留应用程序上 - 所以任何现代现有的库都可能不兼容。

更新

到目前为止,我有这个。 Permissions 表映射到Roles,然后将Roles 分配给用户,并给定上下文。

account_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      |

这个的 SQL 看起来有点像这样......

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 )
    )

);

这行得通,但我确信一定有更好的方法来做到这一点。

下一个问题是如何将层次结构应用于角色? 因此,公司 > 产品 > 区域的“管理员”只能创建角色或更低角色的用户?

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

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

【问题讨论】:

【参考方案1】:

用户表可以有一个卷表的交叉引用,每个卷都有一个特定的角色标识号,带有can_writecan_read 列(等等...)

您的继承权可能如下所示:

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);
[...]

希望这会有所帮助。

【讨论】:

谢谢凯尔,这与我目前的想法相似——我目前正在努力解决的一件事是如何在这些上下文中建立角色层次结构。我会用更多信息更新我的问题。 嘿凯尔,我已经在问题中添加了更多信息,任何指针/建议将不胜感激 - 我在这个问题上绕圈子! 对不起@MattBryson 我不太擅长 SQL - 我会投票赞成这个问题,以便有人可以为您提供更好的帮助。但是,如果您过于依赖设置,您可以使用简单的 PHP 代码来完成大部分操作。

以上是关于基于角色的访问控制 (RBAC) 与上下文?的主要内容,如果未能解决你的问题,请参考以下文章

RBAC 基于角色的访问控制

基于角色的访问控制 (RBAC)权限管理

一个实例:基于RBAC理论的访问控制实践

基于角色与基于资源的权限访问控制

RBAC(Role-Based Access Control)基于角色的访问控制

基于角色的访问控制