简体   繁体   English

Zend 框架:preDispatch ACL 插件导致对不存在的页面的请求被拒绝访问而不是 404

[英]Zend Framework: preDispatch ACL plugin causes requests to non existent page to Access Denied instead of 404

i have setup a preDispatch plugin for my ACL.我已经为我的 ACL 设置了一个 preDispatch 插件。 i have used the controller as resource, action as privilege.我将控制器用作资源,将操作用作特权。 when i try to goto a non existent page, i get to the access denied page instead of 404, i think because the resource and privilege are queried and since they are not found, it goes to the access denied page...当我尝试转到一个不存在的页面时,我进入了访问被拒绝页面而不是 404,我认为是因为查询了资源和权限,并且由于找不到它们,所以它转到访问被拒绝页面...

how can i fix this?我怎样才能解决这个问题? maybe my method of implementing the plugin was wrong?也许我实现插件的方法是错误的? can i somehow have the check for a existent resource b4 my acl plugin runs?我可以以某种方式检查我的 acl 插件运行的现有资源 b4 吗? \\ \\

update更新

plugin code @ pastebin插件代码@ pastebin

I had the same issue and added this to the preDispatch function (using modules though, but it's the $acl->has() function that is interesting):我遇到了同样的问题,并将其添加到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');
    }
}

You can check if action and controller exists (is dispatchable) before checking permissions:您可以在检查权限之前检查操作和控制器是否存在(可调度):

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

I am using this in a controller action helper:我在控制器动作助手中使用它:

$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); 
}

or do not throw an exception, just skip the acl check and let the error handler plugin take care of it .或者不抛出异常,只需跳过 acl 检查并让错误处理程序插件处理它

Note that in this case you cannot use action names that do not correspond to functions in the controller or you will have to create check for that case.请注意,在这种情况下,您不能使用与控制器中的功能不对应的操作名称,否则您必须为这种情况创建检查。

I run into this problem regularly what I use the secure by default model (all web apps I write) and start setting up ACL by denying all.我经常遇到这个问题,我使用默认的安全模型(我编写的所有网络应用程序)并通过拒绝所有内容开始设置 ACL。

Customizing your error controller would work, but I don't think that is the appropriate place to be handling this.自定义您的错误控制器会起作用,但我认为这不是处理此问题的合适场所。

The dispatcher's isDispatchable() method almost works, but it doesn't check the action.调度程序的 isDispatchable() 方法几乎可以工作,但它不会检查操作。 This doesn't sound right, but it makes sense when you consider that you probably want to enable your acl plugin to work with the standard router defaults (module, controller, action).这听起来不对,但是当您考虑可能希望启用 acl 插件以使用标准路由器默认值(模块、控制器、操作)时,这是有道理的。

I am digging deeper to see if there is an elegant way to do this, but for now I stopping denying all and explicitly denying access on a module/controller/action level.我正在深入研究是否有一种优雅的方法可以做到这一点,但现在我停止拒绝所有并明确拒绝模块/控制器/操作级别的访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM