Zugriffskontrollen mit Zend_Acl

0 | 4 Kommentare | 3282 Aufrufe
Sie können diese Wikiseite nach der Anmeldung auf Webmasterpro bearbeiten. Helfen Sie mit und verbessern Sie "Zugriffskontrollen mit Zend_Acl" mit Ihrem Wissen!

Anzeige Hier werben

Einleitung

Nach der Authentifizierung hat man einen eingeloggten Benutzer, aber wie steuert man nun, welcher Benutzer Artikel verfassen darf, welcher Kommentare schreiben darf oder sogar alles bearbeiten und löschen darf? In diesem Beispiel wird genau dieses Problem anhand der Zend_Acl-Komponente beschrieben und gelöst.

Vorbereitung

Benutzer die nicht eingeloggt sind fallen als erstes schonmal in die Rolle "Gast". Dieser Benutzer darf nichts ausser auf der Internetseite rumsurfen und sich Artikel durchlesen. Wenn er nun zu Artikeln Kommentare verfassen will, muss er registriert und eingeloggt sind (Rolle: "Registrierter Benutzer"). Natürlich darf nicht jeder Benutzer, der eingeloggt ist auch gleich Artikel schreiben. Dafür gibt es eine weitere Rolle namens "Autor". Darüber hinaus gibt es noch die Rolle des Administratoren, der alles erstellen, bearbeiten und löschen darf (Rolle: "Administrator").

Hier nochmal eine Zusammenfassung aller Rollen, die wir nun definiert haben:

  • Gast
  • Registrierter Benutzer
  • Autor
  • Administrator

Voraussetzung

Damit ihr die Code-Beispiele genauso testen könnt, wie sie hier beschrieben sind, muss sich das Zend Framework in eurem include_path befinden. Es muss also ein Zend-Verzeichnis im include_path liegen.

Rollen anlegen

Im Skript sähe dies nun wie folgt aus:

 
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php

require_once 'Zend/Acl.php';
$acl = new Zend_Acl;

require_once 'Zend/Acl/Role.php';
$acl->addRole($guest  = new Zend_Acl_Role('Gast'));
$acl->addRole($user   = new Zend_Acl_Role('Registrierter Benutzer'));
$acl->addRole($author = new Zend_Acl_Role('Autor'));
$acl->addRole($admin  = new Zend_Acl_Role('Administrator'));

/* ... */

Bei diesem Beispiel habe ich den Parameter von addRole() jeweils direkt einer Variablen zugewiesen. Dazu gleich mehr.

Vielleicht habt ihr schon beim Lesen vorhin gemerkt, dass sich bei den Berechtigungen eine kleine Hierarchie gebildet hat. Der Gast darf am wenigsten, der registrierte Benutzer darf alles was der Gast auch darf, nur, dass er noch Kommentare verfassen darf. Der Autor darf natürlich auch Kommentare verfassen und der Administrator darf alles was die anderen Rollen auch dürfen.

Beim Aufruf von addRole() kann als zweiten Parameter noch eine Elternrolle definiert werden, von der die aktuelle Rolle ihre Berechtigungen später erben soll.

 
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php

require_once 'Zend/Acl.php';
$acl = new Zend_Acl;

require_once 'Zend/Acl/Role.php';
$acl->addRole($guest  = new Zend_Acl_Role('Gast'));
$acl->addRole($user   = new Zend_Acl_Role('Registrierter Benutzer', $guest));
$acl->addRole($author = new Zend_Acl_Role('Autor', $user));
$acl->addRole($admin  = new Zend_Acl_Role('Administrator', $author));

/* ... */

Nun erben die Rollen ihre Berechtigungen jeweils von der Elternrolle. Hat man, aus irgendeinem Grund, das Objekt der Rolle nicht zur Hand, so kann man auch nur den Namen der Rolle angeben.

Ressourcen definieren

Jetzt fehlen noch die Ressourcen, welche in diesem Beispiel, die einzelnen Sektionen der Internetseite widerspiegeln. Also z.B. das Hinzufügen von Kommentaren oder das Verfassen eines Artikels.

 
PHP
1
2
3
4
5
6
7
8
/* ... */

$acl->add($readArticle  = new Zend_Acl_Resource('Artikel lesen'));
$acl->add($writeArticle = new Zend_Acl_Resource('Artikel verfassen'));
$acl->add($writeComment = new Zend_Acl_Resource('Kommentar verfassen'));
$acl->add($administrate = new Zend_Acl_Resource('Benutzer verwalten'));

/* ... */

Wir haben jetzt drei Ressourcen, die Aktionen definieren, die je nach Rolle bestimmt definiert werden sollen, ob auf sie zugegriffen werden darf oder nicht. Auch hier könnte, durch Angabe eines zweiten Parameters, eine Hierarchie an Ressourcen aufgebaut werden, aber für dieses Beispiel brauchen wir sie nicht.

Berechtigungen definieren

Wir haben also die Rollen und die Ressourcen, jetzt fehlen noch die Definitionen, welche Rolle auf welche Resource zugreifen darf. Dies geschieht über die Methoden allow() (zulassen) und deny() (verweigern).

 
PHP
1
2
3
4
5
6
7
8
9
/* ... */

$acl->deny();                        // Alle Berechtigungen verweigern
$acl->allow($guest,  $readArticle);  // Gast darf Artikel lesen
$acl->allow($user,   $writeComment); // Registrierter Benutzer darf Kommentare schreiben
$acl->allow($author, $writeArticle); // Autor darf Artikel verfassen
$acl->allow($admin,  $administrate); // Administrator darf Benutzer verwalten.

/* ... */

Die erste Zeile ist einfach nur zur Sicherheit da. Damit verweigern wir alle Zugriffe auf Ressourcen, die nicht explizit definiert sind. Das ist sicherer als alle Ressourcen standardmäßig freizugeben und explizit zu verweigern. Besser es meldet sich ein Benutzer, dass er etwas nicht kann, als, dass ein Benutzer Aufgaben tätigen kann, die er nicht darf.

Die drei weiteren Zeilen werden durch ihre Kommentare erklärt, was sie bedeuten bzw. was sie bewirken.

Berechtigungen überprüfen

Nun haben wir Rollen und Ressourcen angelegt und die Berechtigungen korrekt definiert, jetzt fehlt nur noch die Überprüfung, ob eine Rolle auf eine Ressource zugreifen darf. Dies geschieht über die isAllowed()-Methode.

 
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/* ... */

if ($acl->isAllowed($user, $writeComment)) {
    echo "Der registrierte Benutzer darf Kommentare verfassen.\n";
} else {
    echo "Der registrierte Benutzer darf keine Kommentare verfassen.\n";
}

if ($acl->isAllowed($autor, $administrate)) {
    echo "Der Autor darf Benutzer verwalten.\n";
} else {
    echo "Der Autor darf keine Benutzer verwalten.\n";
}

?>

Hierbei würde nun folgende Ausgabe kommen:

 
Text
1
2
Der registrierte Benutzer darf Kommentare verfassen.
Der Autor darf keine Benutzer verwalten.

So kann nun mit nur einer Hand voll Zeilen überprüft werden, ob eine bestimmte Rolle auf eine Ressource zugreifen darf oder nicht.

Erweiterung

Dieses Beispiel beschreibt lediglich einen kleinen Umfang der kompletten Funktionalität.

Privilegien

Es können z.B. auch Privilegien definiert werden. Dafür werden keine Resourcen definiert, die eine Aktion beschrieben (z.B. "Artikel verfassen"), sondern es wird nur ein Objekt definiert (z.B. Artikel). Dazu können dann Privilegien (z.B. verfassen, bearbeiten, löschen, usw.) definiert werden.

Verwandte Artikel


Wikiseite bearbeiten

Diese Seite kann von jedem registrierten Benutzer bearbeitet werden. Bisher haben 3 Personen an der Seite "Zugriffskontrollen mit Zend_Acl" mitgewirkt.

Sie haben einen Fehler entdeckt oder möchten etwas ergänzen? Dann können Sie nach der Anmeldung "Zugriffskontrollen mit Zend_Acl" hier bearbeiten.

Mitarbeiter
  • arbeitet bei der Adcloud GmbH als Software Engineer und beschäftigt sich bereits seit dem Jahr 2000 mit der Entwicklung von dynamischen Internetseiten.
  • graphic, motion & web design - kernreaktor - staportal - mukitu
  • Student der Biochemie und seit einigen Jahren im Hobby-Entwicklerbereich tätig. Stärken in XHTML/CSS und PHP, alles was mit Grafik zu tun hat, gehört nicht dazu.

Kommentare: Zugriffskontrollen mit Zend_Acl

Neuen Kommentar schreiben
Verbindung mit Zend_Auth
Beantworten

Gibt es einen vorgesehen Weg, um eine Verbindung zwischen Zend_Auth und Zend_Acl herzustellen, den wenn ich den Status nicht richtig verwenden kann, bringt er mir ja nichts.

Und ist es nicht wesentlich sinnvoller, die Rechte in ner Tabelle abzulegen, als immer wieder neu die ganzen Nutzer Gruppen und Rechte in seine Controller zu schreiben?

Sebastian Bechtel am 26.05.2009 um 18:02
Re: Verbindung mit Zend_Auth
Beantworten

Zend_Auth kümmert sich nur um die Authentifizierung. Also nur, ob der Benutzer auch der ist, der er meint zu sein. Dies wird in den meisten Fällen über Benutzername und Passwort verifiziert. Zend_Acl dagegen kümmert sich nicht, ob der Benutzer wirklich der ist, wer er angibt zu sein, sondern nur, ob der Benutzer oder die Gruppe auf ein Resource (z.B. auf eine spezielle Seite der Internetseite) zugreifen darf oder nicht. Es handelt sich hier um zwei unterschiedliche Aufgaben.

Wie du nach einer erfolgreichen Authentifizierung an die Benutzerrolle (z.B. eine Gruppe) kommst, ist deine Aufgabe zu definieren bzw. zu implementieren. Da gibt es vom Zend Framework ansich keinen generellen Weg. Es gibt glaube ich ein Projekt, welches sich um genau diese Aufgabe kümmert. Leider habe ich dazu keine URL zur Hand. Ich kann aber nochmal nachschlagen und schauen, ob ich das Projekt finde.

Zu deiner zweiten Frage: Mein Ansatz hier im Artikel ist ein sehr rudimentärer Weg die Rollen und Resourcen zu definieren. Ich wollte nicht sehr weit ausschweifen um Rollen und Resourcen zu beziehen (z.B. aus einer Datenbank). Das habe ich auch indirekt unter "Erweiterung" gesagt. Wenn ich Zeit habe, kann ich ja mal einen Weg beschreiben, diese Daten in einer Datenbank abzulegen.

Ich hoffe, dies konnte deine Fragen beantworten.

Jan Pieper am 26.05.2009 um 20:05
Re: Verbindung mit Zend_Auth
Beantworten

Das das zwei verschiedene Sachen sind, ist natürlich klar, nur gehören sie ja rein logisch doch zusammen, wie du ja aber auch schon gesagt hast. Wenn du den Link zum Projekt noch finden würdest, wär cool.

Sebastian Bechtel am 26.05.2009 um 20:16
Re: Verbindung mit Zend_Auth
Beantworten

Habe die URL von einem Bekannten bekommen: http://code.google.com/p/zfsecurity/

Habs mir aber nun nicht angeschaut, aber ich glaube mich zu erinnern, dass es sowas war, was du suchst.

Jan Pieper am 02.06.2009 um 10:09