Zend Framework: preDispatch ACL plugin causes requests to non existent page to Access Denied instead of 404
Asked Answered
C

4

5

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

Crossarm answered 6/8, 2010 at 7:21 Comment(1)
what if you would post your plugin code?Noellenoellyn
F
4

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');
    }
}
Flatling answered 6/8, 2010 at 10:12 Comment(3)
i havent tried this solution, but i think it will work, except that i did not define acl rules for non protected page. so i think the solution i might use is: if (!acl->has('xxx')) { return true }. this way, the request will continue to be processed and likely result in a 404Crossarm
hey wait a min! i actually already have this setup, thats why it looks so familiar, that check, checks the resource, the action is in the privilege, and that is where the problem lies now.Crossarm
You could also try to modify your ErrorController to catch and redirect an access denied error to your 404 view.Flatling
L
1

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.

Lorikeet answered 18/7, 2011 at 19:43 Comment(0)
J
1

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;
}
Jidda answered 15/4, 2013 at 9:2 Comment(0)
B
1

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.

Bolognese answered 9/6, 2016 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.