2016-09-08 5 views
4

Ich habe eine neue ZF3-Anwendung mit ACL. Jetzt muss ich im Falle eines nicht autorisierten Zugriffs auf eine Fehlerseite umleiten (zum Beispiel 403). Ich denke, der beste Weg ist, um ein Ereignis zu feuern, dann fangen, aber ich nicht ...ZF3-Umleitung nach ACL-Autorisierung fehlgeschlagen

Alles ist in meinem Benutzermodul, in Module.php (Auszüge):

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 ; 
    } 
} 

Aber als mein Ereignis ausgelöst wird, meine dispatchError() Methode wird nie nennen, und 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

Wo bin ich falsch und wie soll ich auslösen/catch dieses Ereignis?

Antwort

3

Da Sie ZF3 verwenden, könnte ich vorschlagen, Ihre ACL-Logik aus dem Bootstrap und in eine Middleware zu verschieben. Wenn die ACL angibt, dass die Anforderung in Ordnung ist, rufen Sie $ next auf, das schließlich zum Controller gelangt. Ist dies nicht der Fall, setzen Sie den Status der Antwort auf 403 und geben die Antwort zurück. Sieh dir die Docks von zend-mvc an, da sie ein Kochbuchbeispiel für genau dieses Problem haben.

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

+0

Es scheint mir, dass diese Antwort meine Frage nicht vollständig beantwortet, aber da es mir Indizes gibt, um den Entwickler zu verbessern, werde ich es mit der Prämie ... Tks vergeben –

0

Auch wenn es nicht das Ereignis Problem nicht lösen, das ist, wie ich das Problem gelöst, Rückkehr die Antwort direkt in meiner checkProtectedRoutes() Methode:

// Erreur 403 
$e->stopPropagation(); 

$baseModel = new ViewModel(); 
$baseModel->setTemplate('403'); 

$resolver = new TemplateMapResolver(); 
$resolver->setMap(['403' => __DIR__ . '/../view/error/403.phtml']); 

// Render view 
$renderer = new PhpRenderer(); 
$renderer->setResolver($resolver); 
$content = $renderer->render($baseModel); 
$response = $e->getResponse(); 
$response->setStatusCode(403); 
$response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseUrl() . '/login'); 
$response->setContent($content); 
return $response ; 
0

ich das gleiche habe Problem. Fehler Trigger bei Ihrer Funktion checkProtectedRoutes(MvcEvent $e) sollte triggerEvent Methode verwenden.

//ACL Permission test   
if (! $auth->hasPermission($e)) { 
    $e->setName(MvcEvent::EVENT_DISPATCH_ERROR); 
    $e->setError('ACL_ACCESS_DENIED');    
    $target = $e->getTarget(); 
    $res = $target->getEventManager()->triggerEvent($e); 
    return $res->last(); 
} 
Verwandte Themen