0
votes

I am implementing separate auth solution for two different modules described in another question by me.

Zend framework 2 : Add different authentication adapter for two different modules

Now in AuthListener file I write code for forward/call to an different controller/action if authentication failed. That is

    $result = $this->adapter->authenticate();

    if (!$result->isValid()) {

        $response = $event->getResponse();

        // Set some response content
        $response->setStatusCode(401);

        $routeMatch = $event->getRouteMatch();
        $routeMatch->setParam('controller', 'First\Controller\Error');
        $routeMatch->setParam('action', 'Auth');
    }

Now I am getting 404 error - "The requested controller was unable to dispatch the request". First I think I do not added route for Error/Auth, but then I verified it got 404 for all other controller/action too. All are directly accessible through their respective route. But forwarding resulting in 404 error. One important thing - I sending authentication request through phpunit to make unit test cases.

UPDATE : route details :

'routes' => array(
    'rest' => array(
        'type' => 'Zend\Mvc\Router\Http\Segment',
        'options' => array(
            'route'    => '/rest[/:id]',
            'constraints' => array(
                'id'     => '[0-9]+',
            ),
            'defaults' => array(
                'controller' => 'First\Controller\Index'
            ),
        ),
    ),
    'error' => array(
        'type'    => 'segment',
        'options' => array(
            'route'    => '/rest-error/[/:action][/:id]',
            'constraints' => array(
                'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                'id'     => '[0-9]+',
            ),
            'defaults' => array(
                'controller' => 'First\Controller\Error',
                'action'     => 'auth',
            ),
        ),
    )
),

'controllers' => array(
    'invokables' => array(
        'First\Controller\Auth' => 'First\Controller\AuthController',
        'First\Controller\Error' => 'First\Controller\ErrorController'
    ),
),

Module.php

$listener = $serviceManager->get('First\Service\AuthListener');
$listener->setAdapter($serviceManager->get('Rest\Service\BasicAuthAdapter'));
$eventManager->getSharedManager()->attach('First', 'dispatch', $listener, 100);

I also tried to use forward instead of above solutio, But that gives error for circular forward Circular forwarding detected: greater than 10 nested forwards. I think event called when forward called.

2
My guess would be that the controller First\Controller\Error doesn't exist...Wilt
@Wilt It exists, Error comes for other controller too like Application\Controller\Index which is default controller. While route works perfectly.kuldeep.kamboj
show your routes for that controllerXerkus
@Xerkus, I updated the router in question, However this should not be requirement as I did not use route. I transfer request to other controller using setParamkuldeep.kamboj
Is your listener connected to MvcEvent::EVENT_ROUTE? Can you show how you connect your listener to an event...?Wilt

2 Answers

0
votes

try to call your action like that : $routeMatch->setParam('action', 'auth');

0
votes

I think the problem might occure because you are listening to MvcEvent::EVENT_DISPATCH. In your listener you set new controller and action variables for RouteMatch but since you are already passed the route event changing those parameters will not have any effect.

You should listen to MvcEvent::EVENT_ROUTE instead and then it will probably work.