1

我正在为ACLin编写一个模块ZF2,我几乎完成了它。

我被卡住的地方是当用户无权访问请求的页面时,我想将用户转发到显示403消息的页面。

我已经尝试将用户重定向403但它会更新URL,所以现在我正在尝试转发用户。

我想做的只是从Module.php. 我试过下面的代码 -

模块.php

if (!$isAllowed) {
    $e->getApplication()->getServiceManager()->get('ControllerPluginManager')->get('forward')->dispatch('acl');
}

使用这个我得到了以下错误 -

未捕获的异常 'Zend\Mvc\Exception\DomainException' 带有消息“转发插件需要一个实现 InjectApplicationEventInterface 的控制器”

我也尝试过用 实现Acl控制器InjectApplicationEventInterface,但问题仍然存在。

你能解释一下如何从Forward另一个开始吗? 如果您需要更多详细信息,请告诉我。ActionModule.php

4

4 回答 4

3

你可以做的是监听 dispatch 事件。您可以在此事件期间更新路由匹配以匹配您自己定义的控制器/操作对以呈现 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);
        }
    }
}

转发是一种在另一个控制器已经被分派时分派控制器的模式。这不是你的情况,正如我从你的问题中读到的那样。所以不要使用转发插件,而是在发送之前修改路由匹配。

于 2013-10-29T08:44:09.797 回答
0

您不能转发,而是重定向到您的 403 页面,如下所示:

if (!$acl->isAllowed()) {
    $response = $e->getResponse();
    $response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseUrl() . '/403page');
    $response->setStatusCode(403);
}
于 2013-10-29T09:01:40.963 回答
0

我认为,如果您想在不更新 url 的情况下向用户发送他处于受限区域的信息,您必须:

  1. 更改显示禁区消息的布局。
  2. 保留原始布局,只需为您的操作切换模板,以便显示禁区消息。

在其中一项操作之后,您只需将 Response 更改为 403。如果这就是您想要的简单操作。对于您想要发送 403 状态的控制器中的任何操作,只需使用:

 $viewModel->setTemplate('partial/noRights');
 $this->getResponse()->setStatusCode('403');
 return $viewModel;

或者,如果您想更改自定义布局:

 $this->layout('layout/custom');
 $this->getResponse()->setStatusCode('403');
 return $viewModel;

您当然可以在模块的引导部分中在 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);
    }
}
于 2013-10-29T11:26:07.493 回答
0

当我实现 ACL 时,我创建了自己的 AUTH 模块用于授权和身份验证。
在该模块中,我创建了 ACL 插件.. 如下所示

//模块.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

}
于 2013-10-29T15:57:09.170 回答