简体   繁体   中英

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. 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...

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? \\

update

plugin code @ 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):

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 .

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.

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. 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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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