我正在ACL
中为ZF2
编写一个模块,而且我差不多完成了它。
我被困的地方是当用户无权访问所请求的页面时,我想转发用户到显示403
消息的页面。
我已尝试重定向用户403
,但它会更新URL
,所以现在我要转到转发用户。
我想做的只是来自Module.php
。我试过下面的代码 -
Module.php
if (!$isAllowed) {
$e->getApplication()->getServiceManager()->get('ControllerPluginManager')->get('forward')->dispatch('acl');
}
使用此我收到以下错误 -
未捕获的异常'Zend \ Mvc \ Exception \ DomainException'及消息'Forward plugin需要一个实现InjectApplicationEventInterface的控制器'
我还试图用Acl
实现InjectApplicationEventInterface
控制器,但问题仍然存在。
您能否请Forward
向Action
解释如何Module.php
到另一个{{1}}?
如果您需要更多详细信息,请与我们联系。
答案 0 :(得分:3)
您可以做的是听取调度事件。您可以在此事件期间更新路由匹配,以匹配您自己定义的控制器/操作对,以呈现403页。
在代码中:
use MvcEvent;
class Module
{
public function onBootstrap($e)
{
$app = $e->getApplication();
$acl = $app->getServiceManager()->get('ACL'); // get your ACL here
if (!$acl->isAllowed()) {
$em = $app->getEventManager();
$em->attach(MvcEvent::EVENT_DISPATCH, function($e) {
$routeMatch = $e->getRouteMatch();
$routeMatch->setParam('controller', 'my-403-controller');
$routeMatch->setParam('action', 'my-403-action');
}, 1000);
}
}
}
转发是在已经调度另一个控制器时调度控制器的模式。这不是你的情况,正如我从你的问题中读到的那样。所以不要使用转发插件,而是在分配之前修改路由匹配。
答案 1 :(得分:0)
您无法转发,但可以重定向到您的403页面,如下所示:
if (!$acl->isAllowed()) {
$response = $e->getResponse();
$response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseUrl() . '/403page');
$response->setStatusCode(403);
}
答案 2 :(得分:0)
我认为,如果你想向用户发送信息,说明他在受限区域而没有更新网址,你必须:
执行其中一项操作后,您只需将响应更改为403。 如果那是你想要的简单的事情。对于控制器中的任何操作,您只想使用发送403状态:
$viewModel->setTemplate('partial/noRights');
$this->getResponse()->setStatusCode('403');
return $viewModel;
或者如果您想更改自定义的布局:
$this->layout('layout/custom');
$this->getResponse()->setStatusCode('403');
return $viewModel;
你当然可以在你的模块的bootstrap部分中添加监听器在event_dispatch上,并检查是否$ acl-> isAllowed()之后你做了我上面写的更改。例如:
public function onBootstrap(MvcEvent $e)
{
$app = $e->getApplication();
$acl = $app->getServiceManager()->get('ACL'); // get your ACL here
if (!$acl->isAllowed()) {
$eventManager = $app->getEventManager();
$sharedEventManager = $eventManager->getSharedManager();
$sharedEventManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, function($e) {
$controller = $e->getTarget(); //controller`s action which triggered event_dispatch
$controller->getResponse()->setStatusCode('403');
$controller->layout('layout/custom');
}, 1000);
}
}
答案 3 :(得分:0)
当我实施ACL时, 我创建了自己的AUTH模块进行授权和身份验证 在那个模块中,我创建了ACL插件......如下所示
// Module.php
/**
* This method is called once the MVC bootstrapping is complete
*
* @param \Zend\EventManager\EventInterface $e
*/
public function onBootstrap(Event $e)
{
$services = $e->getApplication()->getServiceManager();
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach('dispatch', array($this, 'loadConfiguration'), 101);
}
/**
*
* @param \Zend\Mvc\MvcEvent $e
*/
public function loadConfiguration(MvcEvent $e)
{
$e->getApplication()->getServiceManager()
->get('ControllerPluginManager')->get('AclPlugin')
->checkAcl($e); //Auth/src/Auth/Controller/AclPlugin
}
// Auth / src / Auth / Controller / AclPlugin
namespace Auth\Controller\Plugin;
/**
* load libraries here
*/
class AclPlugin extends AbstractPlugin implements ServiceManagerAwareInterface
{
/*
* @var Doctrine\ORM\EntityManager
*/
protected $em;
protected $sm;
/**
* @param Doctrine\ORM\EntityManager $em
* @return string
*/
public function checkAcl($e)
{
$matches = $e->getRouteMatch();
$controller = $matches->getParam('controller');
$action = $matches->getParam('action', 'index');
if ($acl->isAllowed($role, $resource, $permission)) {
return;
} else {
$matches->setParam('controller', 'Auth\Controller\User'); // redirect
$matches->setParam('action', 'accessdenied');
return;
}
}
/// rest of the code here
}