我为我的ACL设置了一个preDispatch插件。我已将控制器用作资源,将操作用作特权。当我尝试转到一个不存在的页面时,我进入拒绝访问页面而不是404,我认为因为查询了资源和权限,并且因为找不到它们,所以它会进入拒绝访问页面...
我该如何解决这个问题?也许我的实现插件的方法是错的?我可以以某种方式检查现有资源b4我的acl插件运行吗? \
插件代码@ pastebin
答案 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检查并让错误处理程序插件处理它。
请注意,在这种情况下,您不能使用与控制器中的功能不对应的操作名称,否则您将不得不为该案例创建检查。