Zend Framework: Beispiel für ein Auth Plugin

Wenn ein Projekt über einen geschlossenen Nutzer- oder Adminbereich verfügt, dann steht man immer wieder vor der Problematik, dass man den Login-Status des Besuchers auf vielen Unterseiten abfragen und ggf. auswerten muss. Bei großen Projekten kann das manchmal ziemlich mühselig werden, doch wenn das Projekt auf dem Zend Framework basiert, dann läßt sich so etwas mit Hilfe der Controller-Plugins sehr schnell umsetzen.

Zunächst benötigen wir innerhalb des Plugin’s die aktive Objekt-Instanz von Zend_Auth. Das unser Beispiel jedoch auch eine Rechteverwaltung auf Basis von Zend_Acl besitzt, lesen wir die dazu notwendige Objekt-Instanz gleich mal mit ein.

$aclObject = Zend_Registry::get('Zend_Acl');
$authObject = Zend_Auth::getInstance();

Im nächsten Schritt müssen wir die Resource- und Privilage Werte für Zend_Acl definieren. Für dieses Beispiel nehmen wir daher an, dass jeder Controller eine Resource darstellt und jede darin enthaltene Action-Methode entspricht der dazu gehörigen Privilage.

So sind wir dann in der Lage, die Zugriffsrechte für die einzelnen Benutzergruppen sehr genau im Projekt zu steuern. Bitte beachten Sie jedoch, dass dieses ein sehr einfaches Beispiel ist, dass aktuell von einem default-Modul ausgeht. Sollten Sie mehrere Modul in Ihrer Applikation einsetzen, so kann es natürlich passieren, dass einzelne Controller-Bezeichnungen doppelt vergeben sind und damit würden sich die Zugriffsrechte der einzelnen Module natürlich überschneiden.

Abhilfe könnte es bei diesem Problem schaffen,statt der Methode getControllerName() den Aufruf von getModuleName() zu nutzen, doch das hätte sicherlich zur Folge, dass die Zugriffsrechte nur auf Modulebene gesteuert werden könnten. Sauberer ist daher vermutlich die Nutzung eines Modulpräfix in der Resource-Bezeichnung.

	
$resource = $request->getControllerName();
$privilage = $request->getActionName();

Nachdem wir die Einstellungen für $resource und $privilage ermittelt haben, müssen wir noch die aktive Benutzerrolle des Besuchers festlegen. In unserem Beispiel gehen wir davon aus, dass die Benutzergruppe in der Spalte Group der Benutzertabelle definiert wurde. Sicherlich gibt es noch viele andere Möglichkeiten, doch für uns Beispiel sollte diese Variante ausreichen.

$role = $authObject->hasIdentity() ? $authObject->getIdentity()->Group : 'guest';

Kommen wir zum wichtigsten Punkt des Plugins: Der Kontrolle der Zugangsberechtigung.

Hier prüfen wir nun endlich mit Hilfe des Zend_Acl Objektes, ob der Besucher über die notwendigen Zugangsberechtigungen für die aufgerufene Seite verfügt. Wenn nicht, leiten wir Ihn durch eine manuelle Aktualisierung des Request-Objektes auf eine entsprechende Fehlerseite um.

if (!$aclObject->isAllowed($role, $resource, $privilage)) {
    $request->setModuleName('default');
    $request->setControllerName('index');
    $request->setActionName('denied');
}

Besitzt ein Besucher die Berechtigung um die angeforderte Seite anzeigen, dann übergeben zusätzlich die ermittelten Daten an Zend_Navigation, denn somit kümmert sich das Navigations-Objekt vollautomatisch darum, dass dem Besucher nur die Punkte in der Navigation angezeigt werden, die er am Ende auch wirklich nutzen darf.

$view = Zend_Layout::getMvcInstance()->getView();
$view->navigation()->setAcl($aclObject);
$view->navigation()->setRole($role);

Das ganze Plugin sieht dann in etwas so aus:

/**
 * @package mountaingrafix.intranet
 * @author Sascha Schoppengerd
 */
class App_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract {

    /**
     * @see Zend_Controller_Plugin_Abstract#dispatchLoopStartup($request)
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)  {

        $aclObject = Zend_Registry::get('Zend_Acl');
        $authObject = Zend_Auth::getInstance();
		
        $resource = $request->getControllerName();
        $privilage = $request->getActionName();

        // Get User Role
        $role = $authObject->hasIdentity() ? $authObject->getIdentity()->Group : 'guest';
		
        // Check User Rights
        if (!$aclObject->isAllowed($role, $resource, $privilage)) {
            $request->setModuleName('default');
            $request->setControllerName('index');
            $request->setActionName('denied');
        }
		
        // ACL to Zend_Navigation
        $view = Zend_Layout::getMvcInstance()->getView();
        $view->navigation()->setAcl($aclObject);
        $view->navigation()->setRole($role);
    }
}

Jetzt müssen Sie eigentlich nur noch dafür sorgen, dass das Plugin auch bei jedem Aufruf vom Frontcontroller geladen wird und dafür bietet sich in der Regel die application.ini an:

resources.frontController.plugins.auth = "App_Controller_Plugin_Auth"

So…das war es schon wieder…ich hofffen jedenfalls, dass Ihnen das kleine Tutorial ein wenig gefallen hat und vielleicht haben Sie ja auch etwas neues gelernt. Ansonsten würde ich mich über Feedback in den Kommentaren natürlich sehr freuen. Verbesserungsvorschläge sind selbstverständlich auch gern gesehen. 😉

2 comments for “Zend Framework: Beispiel für ein Auth Plugin

  1. Theo
    20. November 2011 at 12:53

    Nicht für Newbies geeignet -> dont waste your time

    Trotzdem danke für den Artikel. Bestimmt ist er für Fortgeschrittene geeignet.

  2. mf81de
    8. September 2012 at 12:14

    DANKE! Genau das habe ich gesucht! War am grübeln, wo ich eine Abfrage auf einen eingeloggten User hinpacke, damit diese bei JEDEM Aufruf erfolgt. Bin dabei auf Plugins + preDispatch gestoßen, aber erst durch das Beispiel hier hab ich’s kapiert 😀

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.