alichry/laminas-accesscontrol

laminas 的访问控制

1.0.0 2020-06-28 21:33 UTC

This package is auto-updated.

Last update: 2024-09-26 04:44:56 UTC


README

Build Status codecov

此模块旨在提供一个简单的接口,可以针对与应用程序控制器或控制器动作相关联的访问控制列表进行查询,作为目标资源。这不应直接使用,请使用 https://github.com/alichry/laminas-authorization

接口和实现

访问控制列表的基础接口是 AccessControlListInterface,它提供了 3 个方法

  • identityHasPermission(identity, permission)
  • identityHasRole(identity, role)
  • getAccessStatus(identity, resourceIdentifier)

访问状态 Status 是咨询底层的 ListAdapterInterfaceResourceManagerInterface 的结果。存在多个状态代码

  • 未授权,Status::UNAUTHORIZED:给定的身份未授权,即没有控制器/动作的指定权限或角色。
  • 未认证,Status::UNAUTHENTICATED:给定的身份为 null,因此是无效的。这实际上意味着身份 "null" 是未认证的。这实际上是 alichry/laminas-authorizationalichry/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实例的hasPermissionhasRole方法进行检查。

这在ORM环境中非常有用,例如Doctrine ORM。在创建身份或用户实体类型后,剩下的事情就是实现hasRolehasPermission方法,这些方法可以通过咨询其他ORM实体类型或提供自定义实现来推断。

访问控制列表

AccessControlList是一个通用的ACL,依赖于ResourceManagerListAdapterInterface的实例。只有一个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

这允许您从配置提供工厂构建选项到相应的实例工厂,并且返回的实例将被服务管理器缓存。