api-skeletons / zf-oauth2-doctrine-permissions-acl
Requires
- php: ^7.1
- api-skeletons/zf-oauth2-doctrine: ~2.0 || ^3.0
- api-skeletons/zf-oauth2-doctrine-identity: ~2.0 || ^3.0
- container-interop/container-interop: ^1.1
- gianarb/angry: ^0.1
Requires (Dev)
- api-skeletons/coding-standard: ^1.0
- dprevite/lint: dev-master
- phpstan/phpstan: ^0.9.2
- phpunit/phpunit: ^5.7
- satooshi/php-coveralls: ^1.0
- zendframework/zend-hydrator: ^2.2
- zendframework/zend-i18n: ^2.7
- zendframework/zend-test: ^3.0
- zfcampus/zf-apigility: ^1.3
- zfcampus/zf-apigility-doctrine: ^2.1
README
版本
1.x 用于 PHP 5.5 到 7.0。2.x 用于 PHP 7.1 及以上。
关于
此软件包为 api-skeletons/zf-oauth2-doctrine 提供 ACL。它替换了 zfcampus/zf-mvc-auth 的某些组件,以启用每个用户多个角色,并将角色自动注入到 ACL 中。
此库专门用于角色和用户之间的一对多关系。如果您有一个一对一的关系,其中每个用户可能只有一个角色,则此库不适合您。
此库依赖于 api-skeletons/zf-oauth2-doctrine-identity。请参阅该库以获取实现细节。
实体关系图由 Skipper 创建
安装
此模块的安装使用 composer。有关 composer 文档,请参阅 getcomposer.org。
composer require api-skeletons/zf-oauth2-doctrine-permissions-acl
这将添加到您的应用程序模块列表中
'modules' => array( ... 'ZF\OAuth2\Doctrine\Permissions\Acl', ),
与角色相关的接口
上面的 ERD 显示了 Doctrine 与 Role
实体的关系。要获取用户的角色,用户实体必须实现 ZF\OAuth2\Doctrine\Permissions\Acl\Role\ProviderInterface
。Role
实体必须实现 Zend\Permissions\Acl\Role\RoleInterface
。
角色可能有父级。这是可选的,但在 ACL 中父级关系通常很重要。要创建角色层次结构,您的角色实体必须实现 ZF\OAuth2\Doctrine\Permissions\Acl\Role\HierarchicalInterface
。此接口还实现了 Zend\Permissions\Acl\Role\RoleInterface
。
将角色添加到 ACL 中
要从您的角色实体将角色复制到 ACL 中,请将 config/oauth2.doctrine.permisisons.acl.global.php.dist
复制到您的应用程序 config/autoload/oauth2.doctrine.permisisons.acl.global.php
。
'zf-oauth2-doctrine-permissions-acl' => [ 'role' => [ 'entity' => 'Db\Entity\Role', 'object_manager' => 'doctrine.entitymanager.orm_default', ], ],
这将在 MvcAuthEvent::EVENT_AUTHORIZATION
事件中以优先级 1000 运行。如果您不想自动加载角色,请完全删除 'role' 配置。
添加资源保护
通过以上所有设置,该库已经为在您的资源上创建权限奠定了基础。您可以加载所有角色,并遵循官方Apigility指南:[https://apigility.org/documentation/recipes/how-do-i-customize-authorization-for-a-particular-identity](https://apigility.org/documentation/recipes/how-do-i-customize-authorization-for-a-particular-identity) 确保您的监听器(们)运行在优先级小于1000。
这是链接文章的简要概述。
将此引导程序添加到您的模块中。
namespace Application; use Zend\Mvc\MvcEvent; use Zend\Mvc\ModuleRouteListener; use Application\Authorization\AuthorizationListener; use ZF\MvcAuth\MvcAuthEvent; class Module { public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication()->getEventManager(); $moduleRouteListener = new ModuleRouteListener(); $moduleRouteListener->attach($eventManager); $eventManager->attach( MvcAuthEvent::EVENT_AUTHORIZATION, new AuthorizationListener(), 100 // Less than 1000 to allow roles to be added first && >= 100 ); } }
创建您的授权监听器。
namespace Application\Authorization; use ZF\MvcAuth\MvcAuthEvent; use Db\Fixture\RoleFixture; class AuthorizationListener { public function __invoke(MvcAuthEvent $mvcAuthEvent) { $authorization = $mvcAuthEvent->getAuthorizationService(); // Deny from all $authorization->deny(); // Allow from all for oauth authentication $authorization->addResource('ZF\OAuth2\Controller\Auth::token'); $authorization->allow(null, 'ZF\OAuth2\Controller\Auth::token'); // Add application specific resources $authorization->addResource('FooBar\V1\Rest\Foo\Controller::collection'); $authorization->allow(RoleFixture::USER, 'FooBar\V1\Rest\Foo\Controller::collection', 'GET'); } }
覆盖IS_AUTHORIZED事件
AclAuthorization上的事件管理器允许您覆盖任何ACL调用。例如,如果您有另一个实体,其权限基于其值,您可以在ACL中手动添加新的角色,然后在授权检查时创建覆盖,以允许其他现在作为角色代理的实体值。
use ZF\OAuth2\Doctrine\Permissions\Acl\Event; use Zend\EventManager\Event as ZendEvent; // Allow membership as a role $events = $serviceManager->get('SharedEventManager'); $events->attach( Event::class, Event::IS_AUTHORIZED, function(ZendEvent $event) { if (! $event->getParam('identity') instanceof AuthenticatedIdentity) { return; } $membership = $event->getParam('identity')->getUser()->getMembership(); if ($event->getTarget()->isAllowed($membership->getName(), $event->getParam('resource'), $event->getParam('privilege'))) { $event->stopPropagation(); return true; } }, 100 );