我从 zf2 开始,必须处理多对多权限/角色。使用ZfcRbac .
所以我用用户/层次角色(表名=角色)/权限进行映射
我用拒绝策略做了一些守卫。
我的守卫、 map 、数据库都正常。
我的 HierarchicalRole 实体看起来像:
class HierarchicalRole implements HierarchicalRoleInterface
目前它与 Bakura 给出的原始版本相同。
我的用户实体如下所示:
class User extends ZfcUserEntity implements IdentityInterface
与
/**
* @var \Doctrine\Common\Collections\Collection
* @ORM\ManyToMany(targetEntity="HierarchicalRole")
* @ORM\JoinTable(
* name="user_role_linker",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="idUser")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
protected $roles;
并且角色是通过以下方式构建在构造函数中的:
function __construct() {
$this->roles = new ArrayCollection();
}
使用 zend 开发者工具,我可以看到 ZfcRbac\Collector\RbacCollector
显示了我想要的实际登录用户的所有内容(权限、子级、主要角色等...)。
我的问题是:如何为只能看到被授予访问权限的链接的用户生成动态导航?。并且还在用户未登录时检查连接并在用户登录时隐藏它......
我还是个新手,但如果可能的话,最好有一个很好地解释使用此模块进行良好动态导航的示例。
编辑(5 月 28 日) 到目前为止,我一直在寻求解决方案,我的尝试还没有帮助我。 您可以在这里找到一个: Spiffy navigation 仍然不能完美工作。
最佳答案
我将向您展示 ZfcRbac 如何与 (ZF2) Zend/Navigation 配合使用。 您在数据库中定义了权限,这就是我将省略此部分的原因。
定义您的导航添加页面和权限:
config/global.phpPHP:
return array(
'navigation' => array(
'default' => array(
array(
'label' => 'Contracts',
'route' => 'contract',
'action' => 'list',
'permission' => 'contract.list',
'pages' => array(
array(
'label' => 'New contract',
'route' => 'contract',
'action' => 'add',
'permission' => 'contract.add',
)
)
)
)
),
'service_manager' => array(
'factories' => array(
'navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory',
)
)
);
创建监听器(/module/Application/src/Application/Authorization/RbacListener.php):
<?php
namespace Application\Authorization;
use Zend\EventManager\EventInterface;
use Zend\Navigation\Page\AbstractPage;
use ZfcRbac\Service\AuthorizationServiceInterface;
class RbacListener
{
/**
* @var AuthorizationServiceInterface
*/
protected $authorizationService;
/**
* @param AuthorizationServiceInterface $authorizationService
*/
public function __construct(AuthorizationServiceInterface $authorizationService)
{
$this->authorizationService = $authorizationService;
}
/**
* @param EventInterface $event
* @return bool|void
*/
public function accept(EventInterface $event)
{
$page = $event->getParam('page');
if (!$page instanceof AbstractPage) {
return;
}
$permission = $page->getPermission();
if (is_null($permission)) {
$event->stopPropagation();
return false;
}
$event->stopPropagation();
return $this->authorizationService->isGranted($permission);
}
}
为 RbacListener 创建工厂 (/module/Application/src/Application/Factory/RbacListenerFactory.php):
<?php
namespace Application\Factory;
use Application\Authorization\RbacListener;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class RbacListenerFactory implements FactoryInterface
{
/**
* {@inheritDoc}
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$authorizationService = $serviceLocator->get('ZfcRbac\Service\AuthorizationService');
return new RbacListener($authorizationService);
}
}
将 RbacListenerFactory 添加到 ServiceManager (/module/Application/config/module.config.php):
<?php
return array(
'service_manager' => array(
'factories' => array(
'Application\Authorization\RbacListener' => 'Application\Factory\RbacListenerFactory',
),
),
);
将事件附加到 Zend Navigation View Helper 的 isAllowed 方法(最后将事件附加到 Zend Navigation View Helper 的 isAllowed 方法):
<?php
public function onBootstrap(MvcEvent $event)
{
$application = $event->getApplication();
$eventManager = $application->getEventManager();
$sharedEventManager = $eventManager->getSharedManager;
$serviceManager = $application->getServiceManager();
$rbacListener = $serviceManager->get('Application\Authorization\RbacListener');
$sharedEventManager->attach(
'Zend\View\Helper\Navigation\AbstractHelper',
'isAllowed',
array($rbacListener, 'accept')
);
}
在 View 或布局中呈现菜单:
<?php echo $this->navigation('navigation')->menu(); ?>
我正在使用这段代码,它运行得很好。它基于:
关于php - ZF2 使用 zfcrbac zfcUser 和分层角色策略生成导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22990852/