metarush / perm
基于角色的访问控制(RBAC)和自定义规则(如ABAC)
Requires
- php: >=7.4
- psr/http-message: ^1.0
Requires (Dev)
- laminas/laminas-diactoros: ^2.25
- phpstan/phpstan: ^0.12
- phpunit/phpunit: ^9.1
- roave/security-advisories: dev-master
README
Perm
允许您在应用程序中实现基于角色的访问控制(RBAC)功能,并可选地使用自定义规则(如ABAC)。
安装
通过composer安装 metarush/perm
使用方法
Perm
需要您提供以下数组
- $roleRanks:角色层次结构
- $roleResources:角色可以访问的资源列表
- $resourceRestrictions:资源必须验证后才允许访问的限制列表
array
$roleRanks
一个数组,键代表角色ID,值代表它们的层次结构。例如
$roleRanks = [ 1 => 1, 2 => 2, 3 => 3 ]
键 1
、2
、3
代表应用程序中的角色ID。这可能意味着 1
代表管理员,2
代表版主,3
代表工作人员。
值 1
、2
、3
代表它们的层次结构。 值越小,排名越高。
注意:低级别角色的资源会继承给高级别角色。例如,级别为 3
的角色的资源会继承给级别为 2
和 1
的角色。
array
$roleResources
一个数组,键代表角色ID,值代表具有访问权限的资源ID数组。例如
$roleResources = [ 1 => ['1','2'], 2 => ['3','4'], 3 => ['5','6'] ];
键 1
、2
、3
代表应用程序中的角色ID。这可能意味着 1
代表管理员,2
代表版主,3
代表工作人员。
值 ['1','2']
、['3','4']
、['5','6']
代表应用程序中的资源ID。这可能意味着 1
代表“创建用户”,2
代表“编辑用户”,3
代表“创建帖子”,等等。
您可能已经注意到值是字符串。这是为了您可以真正使用像 'createUser' 这样的字符串作为标识符。这样做,您可以跳过显式创建数字资源ID列表,只要您的应用程序可以处理它。
替代示例
$roleResources = [ 1 => ['createUser', 'editUser'], 2 => ['createPost','editPost'], 3 => ['readPost', 'createComment'] ];
Perm
不关心您如何命名角色或资源。
array
$resourceRestrictions
一个数组,键代表资源ID,值代表允许的约束数组。在 Perm
中,约束由以下公共常量表示
Perm::RESTRICTION_PERMISSION
如果角色具有明确的权限,则允许。例如,“版主”角色具有“创建用户”权限。
Perm::RESTRICTION_CUSTOM_RULE
如果满足自定义规则,则允许
Perm::RESTRICTION_OWNER
如果请求用户是资源的所有者,则允许
Perm::RESTRICTION_CUSTOM_RULE_AND_OWNER
如果满足自定义规则 并且 请求用户是资源的所有者,则允许
Perm::RESTRICTION_PERMISSION_AND_CUSTOM
如果角色具有明确的权限 并且 如果满足自定义规则,则允许
示例
$resourceRestrictions = [ '1' => [ Perm::RESTRICTION_PERMISSION ], '2' => [ Perm::RESTRICTION_PERMISSION, Perm::RESTRICTION_OWNER ], '3' => [ Perm::RESTRICTION_CUSTOM_RULE ], '4' => [ Perm::RESTRICTION_CUSTOM_RULE_AND_OWNER ] '5' => [ Perm::RESTRICTION_PERMISSION_AND_CUSTOM_RULE ] ];
键 1
、2
、3
、4
、5
代表应用程序中的资源ID。这可能意味着 1
代表“创建用户”,2
代表“编辑帖子”,3
代表“删除帖子”,4
代表“删除评论”,5
代表“删除用户”。
值代表 Perm
理解的约束。这是 Perm
解释上述示例的方式
-
资源ID
1
或“创建用户”资源,如果请求用户的角色具有明确的“创建用户”权限,则允许。 -
资源ID
2
或“编辑帖子”资源,如果请求用户的角色具有明确的“编辑帖子”权限,或者请求用户是资源的所有者,则允许。 -
资源ID
3
或 "删除帖子" 资源,如果满足自定义规则,则允许。例如,您可以设置任何规则,如 "如果 x,则可以删除帖子"。只要返回布尔值,您就可以在您的代码中自定义规则。 -
资源ID
4
或 "删除评论" 资源,如果满足自定义规则,并且请求用户是该资源的所有者,则允许。 -
资源ID
5
或 "删除用户" 资源,如果角色具有显式权限并且满足自定义规则,则允许。
如您在资源ID 2
中所见,您可以按需组合限制。
当使用组合限制时,只需要一个验证通过的限制即可授予访问权限。 例如,在资源ID 2
中,如果用户具有资源ID 2
的显式权限或者自定义规则验证通过,则授予访问权限。
可选自定义类
PermissionInterface
$ownerFinder
您创建的此自定义类将用作特定资源的所有者查找器。
所需
-
Perm::RESTRICTION_OWNER
-
Perm::RESTRICTION_CUSTOM_RULE_AND_OWNER
使用构建器中的 ->setOwnerFinderFactoryFqn($ownerFinderFactoryFqn)
方法应用此自定义类,您还需要创建一个工厂类。
PermissionInterface
$customRules
您创建的此自定义类将用作特定资源的自定义规则处理器。
所需
-
Perm::RESTRICTION_CUSTOM_RULE
-
Perm::RESTRICTION_CUSTOM_RULE_AND_OWNER
-
Perm::RESTRICTION_PERMISSION_AND_CUSTOM_RULE
使用构建器中的 ->setCustomRulesFactoryFqn($customRulesFactoryFqn)
方法应用此自定义类,您还需要创建一个工厂类。
总结一下,如果您要创建所有者查找器类,则需要创建一个工厂类来实例化和返回您的所有者查找器类。同样,如果您要创建自定义规则类,也需要为它创建一个工厂类。
有关如何实现这些自定义类的示例,请参阅 tests/unit/Samples
文件夹。
初始化库
在您的中间件、控制器或应用的顶部
use MetaRush\Perm; $perm = (new Perm\Builder) ->setRoleRanks($roleRanks) ->setRoleResources($roleResources) ->setResourceRestrictions($resourceRestrictions) ->setOwnerFinderFactoryFqn(Perm\Samples\MyOwnerFinderFactory::class) // optional ->setCustomRulesFactoryFqn(Perm\Samples\MyCustomRulesFactory::class) // optional ->build();
创建一个 Request
对象
$userId = 5; // userId of the requesting user $roleId = 3; // roleId of $userId e.g., "staff" $resourceId = 'addUser'; // resourceId of the requested resource $serverRequest = $psr7serverRequest; // optional PSR-7 ServerRequestInterface object $request = new Perm\Request($userId, $roleId, $resourceId, $serverRequest);
上述值取决于您的应用。可选的 $serverRequest
参数可用于您的自定义规则。
将 Request
对象传递给 Perm
的 hasPermission()
方法
if (!$perm->hasPermission($request)) exit('Access denied'); // access allowed, continue with the app...
这是使用 Perm
的基本思路。CRUD 功能或用户、角色和资源的数据库不包括在此库中,因为它们最好在用户层实现 -- 因为它们通常每个项目都是独特的。重要的是要记住,使它们与之前讨论的 Perm
所需的三个数组兼容。
- $roleRanks
- $roleResources
- $resourceRestrictions