Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZF3 redirection after ACL authorization failed

I have a new ZF3 application with ACL. Now I need, in case of unauthorized access, to redirect to an error page (403 for example). I think the best way is to fire an event, then catch it, but I failed...

All is in my User module, in Module.php (extracts):

namespace User;

use Zend\Mvc\MvcEvent;
use Zend\Permissions\Acl\Acl;
use Zend\Stdlib\Response ;
use Zend\View\Model\ViewModel;
[...]

class Module implements ConfigProviderInterface
{
    [...]

    public function onBootstrap(MvcEvent $e)
    {
        // Set event to check ACL, then to handle unauthorized access
        $eventManager = $e->getApplication()->getEventManager();
        $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'checkProtectedRoutes'), 1);
        $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'dispatchError'), -999);
        // Init ACL
        $this->initAcl($e);
    }

    public function initAcl(MvcEvent $e)
    {
        [...]
    }

    public function checkProtectedRoutes(MvcEvent $e)
    {
        // My access logic working fine. return if OK
        [...]

        // if authorization failed
        $e->setError('ACL_ACCESS_DENIED') ;
        $e->setParam('route', $route);
        $e->getTarget()->getEventManager()->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $e);
    }

    public function dispatchError(MvcEvent $e)
    {
        // Check error type
        $error = $e->getError();
        switch ($error) {
            case 'ACL_ACCESS_DENIED' :
                // What should I do here ?

                break;
            default:
                return ;
            break;
        }
        return false ;
    }
}

But when my event is triggered, my dispatchError() method is never call, and ZF3 cry:

Catchable fatal error: Argument 1 passed to Zend\Mvc\View\Http\RouteNotFoundStrategy::detectNotFoundError() must be an instance of Zend\Mvc\MvcEvent, instance of Zend\EventManager\Event given, called in /xxxxxxx/vendor/zendframework/zend-eventmanager/src/EventManager.php on line 271 and defined in /xxxxxxxx/vendor/zendframework/zend-mvc/src/View/Http/RouteNotFoundStrategy.php on line 135

Where I am wrong and how should I trigger/catch this event ?

like image 685
Al Foиce ѫ Avatar asked Oct 19 '22 02:10

Al Foиce ѫ


1 Answers

Since you're using ZF3, I might suggest moving your ACL logic out of the bootstrap and into a middleware. If the ACL says the request is okay, you call $next which eventually gets to the controller. If it is not, you set the status on the response to 403 and return the response. Check out the docks on zend-mvc as they have a cookbook example for this very problem.

https://docs.zendframework.com/zend-mvc/cookbook/middleware-in-listeners/

like image 53
Jeremy Giberson Avatar answered Oct 21 '22 06:10

Jeremy Giberson