我正在使用 Yii RBAC 来控制用户对我的应用程序的访问,它由三个 mySql 表组成;
authitem
(RBAC 角色项)
authitemchild
(属于其他角色的任何 RBAC 规则)
authitemassignment
(为用户分配角色)
例如,我们可能有这样的表:
授权:
| name (pk) |
areaASuperUser
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBSuperUser
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
authitemchild
| parent (pk) | child (pk) |
areaASuperUser areaACreateOnly
areaASuperUser areaAReadOnly
areaASuperUser areaAUpdateOnly
areaASuperUser areaADeleteOnly
areaBSuperUser areaBCreateOnly
areaBSuperUser areaBReadOnly
areaBSuperUser areaBUpdateOnly
areaBSuperUser areaBDeleteOnly
auithitemassignment
| itemname (pk) | userid (pk) |
areaASuperUser 1
在上述场景中,id 为 1 的用户在 areaA 中具有完整的 CRUD 访问权限。我需要的是用户无权访问的所有角色的列表,我还需要考虑他们也有权访问的任何角色的子级。
我可以轻松获取用户无权访问的所有角色:
SELECT DISTINCT `ai`.`name`
FROM `authitem` `ai`
LEFT JOIN `authassignment` `aa`
ON `aa`.`itemname` = `ai`.`name` AND `aa`.`userid` = 1
WHERE `aa`.`itemname` IS NULL
但这会返回:
| name |
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBSuperUser
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
而且因为所有 areaA* 角色都是 areaASuperUser 的孩子,所以我不希望它们返回。
任何建议或推动正确方向将不胜感激!
*编辑:
谢谢@SuVeRa,你的回答:
SELECT DISTINCT `ai`.`name`
FROM `authitem` `ai`
LEFT JOIN `authassignment` `aa`
ON `aa`.`itemname` = `ai`.`name` AND `aa`.`userid` = 1
WHERE
`aa`.`itemname` IS NULL
AND `ai`.`name` NOT IN (
SELECT
`aic`.`child` itemname
FROM `authitemchild` `aic`
JOIN `authassignment` `aa`
ON `aa`.`itemname` = `aic`.`parent`
WHERE `aa`.`userid` = 1
)
非常适合上面的示例,但是我刚刚扩展了应用程序以包含多个儿童级别,即
授权:
| name (pk) |
areaABSuperUser
areaASuperUser
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBSuperUser
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
areaCSuperUser
areaCCreateOnly
areaCReadOnly
areaCUpdateOnly
areaCDeleteOnly
authitemchild
| parent (pk) | child (pk) |
areaABSuperUser areaASuperUser
areaABSuperUser areaBSuperUser
areaASuperUser areaACreateOnly
areaASuperUser areaAReadOnly
areaASuperUser areaAUpdateOnly
areaASuperUser areaADeleteOnly
areaBSuperUser areaBCreateOnly
areaBSuperUser areaBReadOnly
areaBSuperUser areaBUpdateOnly
areaBSuperUser areaBDeleteOnly
areaCSuperUser areaCCreateOnly
areaCSuperUser areaCReadOnly
areaCSuperUser areaCUpdateOnly
areaCSuperUser areaCDeleteOnly
auithitemassignment
| itemname (pk) | userid (pk) |
areaABSuperUser 1
原来的答案会回来;
| name |
areaACreateOnly
areaAReadOnly
areaAUpdateOnly
areaADeleteOnly
areaBCreateOnly
areaBReadOnly
areaBUpdateOnly
areaBDeleteOnly
areaCSuperUser
areaCCreateOnly
areaCReadOnly
areaCUpdateOnly
areaCDeleteOnly
因为它过滤掉了父母和孩子,而不是孩子的孩子。我追求的结果(在第二个例子中)是:
| name |
areaCSuperUser
areaCCreateOnly
areaCReadOnly
areaCUpdateOnly
areaCDeleteOnly
***编辑2:
专门针对 Yii:
我对 Yii 做了更多的阅读,CAuthManager有许多有用的方法,包括hasItemChild()、isAssigned()、getItemChildren()等,它们可以帮助抓取我需要的数据