How to control permission using ACL for each controller


I want to control permission using ACL for each controller (or Modlues).

I tried to use isAllow() in __constructer, and if denied, I would redirect to an error page from __constructer using $this->redirect()->toURL(). But I couldn’t redirect with error as follow.

Service with name "XXXXX\Controller\HomeController" could not be created. Reason: Redirect plugin requires event compose a response

Is there any recommended way to implement it?

No, because you must copy code and this is never recommended.

Use a listener that listens for the mvc-event EVENT_DISPATCH. In the listener you have access to the request, application with service-manager and so on.

Within the listener you can fetch authentication service to get the identity and your ACL. Via the route match you have access to the currently called route name, controller and action.

A new target can be set via the route match. Example:

$routeMatch->setParam('controller', \MyModule\Controller\IndexController::class);

if ($role === 'guest') {
    $routeMatch->setParam('action', 'login');
} else {
    $routeMatch->setParam('action', 'forbidden');
1 Like

Thank you for your advice again, and even for sample code.

I see it. The listener seems that an interrupt handler in an embedded system.

Thank you for your advice.

Here is another example of a listener: Setting module-specific Layouts - laminas-view - Laminas Docs

There is also an example with ACL somewhere, but I can’t find it. :see_no_evil:

Thank you for your information.

This seems to have a wide range of applications.
I hadn’t even looked at the cookbook…