Zend Framework:preDispatch ACL插件导致对不存在的页面的请求为Access Denied而不是404

时间:2010-08-06 07:21:10

标签: php zend-framework acl

我为我的ACL设置了一个preDispatch插件。我已将控制器用作资源,将操作用作特权。当我尝试转到一个不存在的页面时,我进入拒绝访问页面而不是404,我认为因为查询了资源和权限,并且因为找不到它们,所以它会进入拒绝访问页面...

我该如何解决这个问题?也许我的实现插件的方法是错的?我可以以某种方式检查现有资源b4我的acl插件运行吗? \

更新

插件代码@ pastebin

4 个答案:

答案 0 :(得分:4)

我遇到了同样的问题并将其添加到preDispatch函数中(虽然使用了模块,但它是有趣的$acl->has()函数):

if (!$acl->has($request->module . '_' . $request->controller)) {
    // action/resource does not exist in ACL
    $request->setModuleName('default');
    $request->setControllerName('error');
    $request->setActionName('notfound');
} else {
    // resource does exist, check ACL
    if (!$acl->isAllowed($role, $module . '_' . $controller, $action)) {
        $request->setControllerName('user');
        $request->setActionName('login');
    }
}

答案 1 :(得分:1)

我经常遇到这个问题,我默认使用安全模型(我编写的所有网络应用程序)并开始通过拒绝所有人来设置ACL。

自定义错误控制器会起作用,但我不认为这是处理它的合适位置。

调度程序的isDispatchable()方法几乎可以正常工作,但它不会检查操作。这听起来不对,但是当您考虑到您可能希望启用您的acl插件以使用标准路由器默认值(模块,控制器,操作)时,这是有道理的。

我正在深入研究是否有一种优雅的方法来做到这一点,但是现在我停止拒绝所有并明确拒绝模块/控制器/动作级别的访问。

答案 2 :(得分:1)

您可以在检查权限之前检查操作和控制器是否存在(可分派):

$front = Zend_Controller_Front::getInstance();
if (!$front->getDispatcher()->isDispatchable($request)) {
    throw new Zend_Exception('Page not found', 404);
    return false;
}

答案 3 :(得分:1)

我在控制器动作助手中使用它:

$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
$actionMethodName = $dispatcher->formatActionName($this->getRequest()->getActionName()
if (!dispatcher->isDispatchable($request) || !in_array($actionMethodName, get_class_methods($this->getActionController()))) {
     throw new Zend_Controller_Action_Exception('Page not found', 404); 
}

或者不抛出异常,只需跳过acl检查并让错误处理程序插件处理它。

请注意,在这种情况下,您不能使用与控制器中的功能不对应的操作名称,否则您将不得不为该案例创建检查。