2016-06-08 148 views
3

我試圖實現RBAC,但用戶可以擁有多個角色,每個角色在特定的上下文之下。帶上下文的基於角色的訪問控制(RBAC)?

上下文基於3個因子,Company,ProductRegion

所以用戶A可以是公司1的Admin,而且也是公​​司2>產品3的Viewer> 4區

,這是什麼樣的RBAC的最好的辦法設置?

我現在正在進行這項工作,因此尋找結構化數據庫表的最佳方法,以便實現此級別的粒度訪問。

不幸的是,這是遺留在運行PHP CodeIgniter/mySQL的應用程序 - 所以任何現代現有的庫可能不兼容。

UPDATE

我有這個至今。 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 [email protected]) 

     #if the user is product admin 
     OR (ur.role_id = 3 AND [email protected] AND [email protected]) 

     #if the user is any other role then the need explicit access 
     OR (ur.role_id > 3 AND [email protected] AND [email protected] AND [email protected]) 
    ) 

); 

這工作,但我敢肯定,必須有一個更好的方式來做到這一點。

接下來的問題是如何將層次結構應用於角色?
因此,公司>產品>地區的「管理員」只能創建其角色或更低角色的用戶?

我將不得不查看他們在上下文中分配的角色,然後返回排名低於用戶級別的每個角色?

這個上下文可以更好地放置爲一個字符串嗎? '1.3.gb'/'1.2'?然後,當查找角色時,我首先形成上下文字符串?

回答

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

希望這有助於。

+0

感謝凱爾,這與我到目前爲止所做的相似 - 我現在正在努力的一件事是如何在這些上下文中擁有角色層次結構。生病更新我的問題與一些更多的信息。 –

+0

嘿凱爾,我已經添加了一些更多的信息的問題,任何指針/建議將不勝感激 - 我要圍繞這一個圓圈! –

+0

對不起@MattBryson我對SQL不太好 - 我會投票回答這個問題,這樣有人可以給你一些更好的幫助。但是,如果您想要在設置上過多,則可以通過簡單的PHP代碼實現其中的大部分功能。 – KDOT