Hy,
for one of my projects I would like to use zend-navigation with Acl and an authorization middleware. But despite all my attempts I can not do it and at the same time could you tell me if it’s the right approach.
About zend-navigation I did this:
I have this in my configuration :
'acl' => [
        'roles' => [
            'visiteur'          =>  [],
            'membre'            =>  ['visiteur'],
            'administrateur'    =>  ['membre'],
        ],
        'resources' => [
            'administrateur.action',
            'membre.action',
            'visiteur.action',
            'login.action'
        ],
        'allow' => [
            'administrateur'    => ['administrateur.action'],
            'membre'            => ['membre.action'],
            'visiteur'          => ['visiteur.action', 'login.action'],
        ],
        'deny'  =>  [
            'administrateur'    =>  ['login.action'],
            'membre'            =>  ['login.action'],
        ]
    ],
    'navigation' => [
        'menu_gauche' => [
            [
                'label'     =>  'Boite à outils',
                'route'     =>  'outils',
                'resource'  =>  'membre.action',
            ],
            [
                'label'     =>  'Administration',
                'route'     =>  'admin',
                'resource'  =>  'administrateur.action',
            ],
        ],
        'menu_droit' => [
            [
                'label' => 'Connexion',
                'route' => 'login',
                'resource'  =>  'login.action',
            ],
            [
                'label' => 'déconnexion',
                'route' => 'logout',
                'resource'  =>  'membre.action',
            ],
        ],
    ],
    'event_manager'   => [
        'lazy_listeners' => [
            [
                'listener' => Application\Listener\NavigationListener::class,
                'method'   => 'addAcl',
                'event'    => Zend\Mvc\MvcEvent::EVENT_RENDER,
                'priority' => -100,
            ],
        ],
    ],
In my Module.php :
public function getServiceConfig()
    {
        return [
            'factories' => [
                Listener\NavigationListener::class => InvokableFactory::class,
                Middleware\AuthorizationMiddleware::class  =>  ConfigAbstractFactory::class,
            ],
        ];
    }
    /**
     * {@inheritDoc}
     * @see \Zend\ModuleManager\Feature\BootstrapListenerInterface::onBootstrap()
     */
    public function onBootstrap(\Zend\EventManager\EventInterface $e)
    {
        $application = $e->getApplication();
        $eventManager = $application->getEventManager();
        $services     = $application->getServiceManager();
        $config = $application->getServiceManager()->get('config');
        
        $eventManager->attach($e::EVENT_DISPATCH, function ($e) use ($services) {
            $request  = Psr7ServerRequest::fromZend($e->getRequest());
            $response = Psr7Response::fromZend($e->getResponse());
            $done     = function ($request, $response) {
            };
            
            $authorizationMiddelware = $services->get(Middleware\AuthorizationMiddleware::class);
            
            
            $result   = $authorizationMiddelware(
                $request->withAttribute('mvcEvent', $e),
                $response,
                $done
            );
            
            if ($result) {
                return Psr7Response::toZend($result);
            }
        }, 2);
        if (array_key_exists('event_manager', $config)
            && is_array($config['event_manager'])
            && array_key_exists('lazy_listeners', $config['event_manager'])
        ) {
            $aggregate = new LazyListenerAggregate(
                $config['event_manager']['lazy_listeners'],
                $application->getServiceManager()
            );
            $aggregate->attach($application->getEventManager());
        }
    }
In my NavigationListener.php :
class NavigationListener
{
    /**
     * @param MvcEvent $event
     */
    public function addAcl(MvcEvent $event)
    {
        $serviceManager = $event->getApplication()->getServiceManager();
        /**
         * @var \Zend\View\HelperPluginManager $helperPluginManager
         */
        $helperPluginManager = $serviceManager->get('ViewHelperManager');
        /**
         * @var \Zend\View\Helper\Navigation $plugin
         */
        $plugin = $helperPluginManager->get('navigation');
        /**
         * @var Acl $acl
         */
        $acl = $serviceManager->get(AclFactory::class);
        /**
         * @var Container $session
         */
        $session = $serviceManager->get(Session::class);
        $role = ($session->offsetExists('role'))? $session->offsetGet('role') : 'visiteur';
        $plugin->setDefaultAcl($acl);
        $plugin->setRole($role);
        $this->configureMenuHelper($plugin->menu());
    }
    private function configureMenuHelper(Menu $menu)
    {
        $menu->setPartial('partials/menu');
    }
}
In my AuthorizationMiddleware.php :
class AuthorizationMiddleware
{
    /**
     * @var Acl
     */
    private $acl;
    /**
     * @var Container
     */
    private $session;
    public function __construct(
        Acl $acl,
        Container $session
    ) {
        $this->acl = $acl;
        $this->session = $session;
    }
    public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next = null)
    {
        /**
         * @var MvcEvent $mvcEvent
         */
        $mvcEvent= $request->getAttribute('mvcEvent');
        $role = ($this->session->offsetExists('role'))
            ? $this->session->offsetGet('role')
            : 'visiteur';
        $routeParam = $mvcEvent->getRouteMatch()->getParams();
        $resource = (isset($routeParam['resource']))? $routeParam['resource'] : 'visiteur.action';
        if (! $this->acl->isAllowed($role, $resource)) {
            return new RedirectResponse('/login', 403);
        }
    }
}
With this code I get a blank page, and despite all my attempts I do not see how to return the correct answer from the authorization middleware,
Thank you in advance for your suggestions, advice or good practices.
PS: if you are missing code to help me to the solution do not hesitate.
cordially