我正在尝试实施RBAC,但用户可以拥有多个角色,每个角色都在特定的上下文下。
上下文基于3个因素,Company
,Product
和Region
。
因此,用户A可以是公司1的Admin
,也可以是公司2的Viewer
&gt; <产品3> 4区
这种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 |
然后分配给用户和给定上下文。
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'?然后在查找角色时,我首先形成上下文字符串?
答案 0 :(得分:0)
用户表可以对滚动表进行交叉引用,每个卷都有一个特定的角色标识号,其中包含can_write
,can_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);
[...]
希望这会有所帮助。