alichry / laminas-accesscontrol
laminas 的访问控制
Requires
- php: ^7.1
- laminas/laminas-mvc: ^3.1
- laminas/laminas-servicemanager: ^3.4
Requires (Dev)
- phpunit/phpunit: ^7.5
This package is auto-updated.
Last update: 2024-09-26 04:44:56 UTC
README
此模块旨在提供一个简单的接口,可以针对与应用程序控制器或控制器动作相关联的访问控制列表进行查询,作为目标资源。这不应直接使用,请使用 https://github.com/alichry/laminas-authorization
接口和实现
访问控制列表的基础接口是 AccessControlListInterface
,它提供了 3 个方法
- identityHasPermission(identity, permission)
- identityHasRole(identity, role)
- getAccessStatus(identity, resourceIdentifier)
访问状态 Status
是咨询底层的 ListAdapterInterface
和 ResourceManagerInterface
的结果。存在多个状态代码
- 未授权,
Status::UNAUTHORIZED
:给定的身份未授权,即没有控制器/动作的指定权限或角色。 - 未认证,
Status::UNAUTHENTICATED
:给定的身份为 null,因此是无效的。这实际上意味着身份 "null" 是未认证的。这实际上是alichry/laminas-authorization
和alichry/laminas-accesscontrol
之间的短路,因为传递的身份是 null,通常从laminas/laminas-autthentication
中的AuthenticationService
获取。 - 拒绝,
Status::REJECTED
:如果控制器/动作具有 "拒绝所有",或推断策略是 "拒绝所有"。 - 公开,
Status::PUBLIC
:公开可访问,无需认证或授权。 - 正常,
Status::OK
:给定的身份已授权但不必定已认证,即给定的身份具有控制器/动作的指定权限或角色。这并不意味着用户已认证。检查是否已认证是alichry/laminas-authorization
的目的。
ArrayAccessControlList
ArrayAccessControlList
依赖于传递的身份、权限、角色和控制器访问级别列表来推断访问状态。
存在两种模式
- 严格,
ArrayListAdapter::MODE_STRICT
模式:所有身份必须在列表中定义,未定义的引用身份将抛出异常。引用身份的角色必须在角色列表中定义。身份列表中引用的权限也应在权限列表中。如果缺少条目,将抛出异常。 - 宽松,
ArrayListAdapter::MODE_CHILL
模式:一些身份可以从配置中省略,这会导致ArrayAccessControlList
假设省略的身份没有任何权限。如果在身份列表中引用了权限但不在权限列表中,则不会抛出异常。
策略处理资源列表中缺失条目的默认访问级别
- 拒绝:如果目标资源未找到,则拒绝所有请求。
- 认证:如果目标资源未找到,则假设它需要认证。
- 接受:如果目标资源未找到,则假设它是公开可访问的。
示例
<?php use AliChry\Laminas\AccessControl\ArrayAccessControlList as ACL; use AliChry\Laminas\AccessControl\Lists\ArrayListAdapter as LA; use AliChry\Laminas\AccessControl\Resource\ResourceIdentifier; $controllers = [ TestController::class => ACL::ACCESS_ALL, TestAuthController::class => ACL::ACCESS_AUTHENTICATED_ONLY, TestMultipleController::class => [ // methods 'getAction' => ACL::ACCESS_ALL, 'disable' => ACL::ACCESS_REJECT_ALL, 'admin' => ACL::role('admin'), 'editAction' => ACL::permission('edit') ] ]; $identities = [ 'admin@test.com' => [ 'roles' => [ 'admin' ], 'permissions' => [] ] ]; $roles = [ 'admin' => [ 'special-admin-perm' ] ]; $permissions = [ 'special-admin-perm', 'edit' ]; $acl = new ACL( LA::MODE_STRICT, ACL::POLICY_REJECT, $controllers, $identities, $roles, $permissions ); $unauthStatus = $acl->getAccessStatus( 'admin@test.com', new ResourceIdentifier( TestMultipleController::class, 'editAction' ) ); echo 'Code: ' . $unauthStatus->getCode() . PHP_EOL; // Code: -3 (UNAUTHORIZED) echo 'Identity: ' . $unauthStatus->getIdentity() . PHP_EOL; // Identity: admin@test.com echo 'Messages: ' . implode(', ', $unauthStatus->getMessages()) . PHP_EOL; // Identity "admin@test.com" requires perm:edit $okStatus = $acl->getAccessStatus( 'admin@test.com', new ResourceIdentifier( TestMultipleController::class, 'admin' ) ); echo 'Code: ' . $okStatus->getCode() . PHP_EOL; // Code: 1 (OK) echo 'Identity: ' . $okStatus->getIdentity() . PHP_EOL; // Identity: admin@test.com echo 'Messages: ' . implode(', ', $okStatus->getMessages()) . PHP_EOL; //
IdentityAccessControlList
IdentityAccessControlList
不关注数组以推断访问状态。它依赖于 ResourceManagerInterface
的实例,并且传递的身份应该是 IdentityInteface
的实例。
传入的资源管理器将为每个资源(控制器/操作)提供策略(访问级别)。如果资源需要身份验证或授权,我们将通过调用传入的IdentityInterface
实例的hasPermission
或hasRole
方法进行检查。
这在ORM环境中非常有用,例如Doctrine ORM。在创建身份或用户实体类型后,剩下的事情就是实现hasRole
和hasPermission
方法,这些方法可以通过咨询其他ORM实体类型或提供自定义实现来推断。
访问控制列表
AccessControlList
是一个通用的ACL,依赖于ResourceManager
和ListAdapterInterface
的实例。只有一个ListAdapterInterface
实现,即ArrayListAdapter
,它被ArrayAccessControlList
使用。
配置
您可以在config/modules.config.php
。每个服务条目应包含名称作为键,映射到服务,通常是FQCN,或者是一个包含以下键的数组
- service: 已注册到服务管理器的服务
- options: 将传递给引用服务的相应工厂的数组
请注意,引用服务名称应在服务管理器中注册相应的工厂。
注册的服务也可以通过以下方式从服务管理器检索
- alichry.access_control.list.$key
- alichry.access_control.list_adapter.$key
- alichry.access_control.resource_manager.$key
这允许您从配置提供工厂构建选项到相应的实例工厂,并且返回的实例将被服务管理器缓存。