| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 15156 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.auth.introduction">
- <title>Einführung</title>
- <para>
- <classname>Zend_Auth</classname> bietet eine API für das Authentifizieren und enthält konkrete
- Authentifizierungs-Adapter für übliche Use Case Szenarien.
- </para>
- <para>
- <classname>Zend_Auth</classname> behandelt nur die <emphasis role="strong">Authentifizierung</emphasis>
- und nicht die <emphasis role="strong">Authorisierung</emphasis>. Authentifizierung ist lose
- definiert als das Ermitteln ob eine Entität aktuell das ist was Sie vorgibt zu sein (z.B.
- Identifizierung), basierend auf einem Set von Zeugnissen. Authorisierung, der Prozess des
- Entscheidens ob es einer Entität erlaubt wird auf andere Entitäten Zugriff zu erhalten,
- oder um auf diesen Operationen durchzuführen, ist ausserhalb der Möglichkeit von
- <classname>Zend_Auth</classname>. Für weitere Informationen über Authorisierung und Zugriffskontrolle
- mit dem Zend Framework, sollte <link linkend="zend.acl"><classname>Zend_Acl</classname></link>
- angeschaut werden.
- </para>
- <note>
- <para>
- Die <classname>Zend_Auth</classname> Klasse implementiert das Singleton Pattern - nur eine Instanz der
- Klasse ist vorhanden - durch Ihre statische <code>getInstance()</code> Methode. Das bedeutet das
- die Verwendung des <code>new</code> Operators und des <code>clone</code> Keywords mit der
- <classname>Zend_Auth</classname> Klasse nicht funktioniert; stattdessen muß <classname>Zend_Auth::getInstance()</classname>
- verwendet werden.
- </para>
- </note>
- <sect2 id="zend.auth.introduction.adapters">
- <title>Adapter</title>
- <para>
- Ein <classname>Zend_Auth</classname> Adapter wird verwendet um sich gegenüber einem speziellen
- Typ von Authentifizierungs Services zu authentifizieren, wie LDAP, RDBMS, oder
- Datei-basierenden Speichern. Verschiedene Adapter besitzen leicht unterschiedliche
- Optionen und Verhaltensweisen, aber einige grundlegende Dinge sind für
- Authentifizierungs Adapter üblich. Zum Beispiel das die Authentifizierung Zeugnisse
- akzeptiert werden (enthält auch vorgegebene Identitäten), das Abfragen am
- Authentifizierungsservice durchgeführt werden, und das Ergebnisse zurückgegeben werden,
- sind für <classname>Zend_Auth</classname> Adapter üblich.
- </para>
- <para>
- Jede <classname>Zend_Auth</classname> Adapter Klasse implementiert <classname>Zend_Auth_Adapter_Interface</classname>. Dieses
- Interface definiert eine Methode, <code>authenticate()</code>, die eine Adapter Klasse implementieren
- muß um eine Authentifizierungsanfrage auszuführen. Jede Adapter Klasse muß vorher vorbereitet sein
- bevor <code>authenticate()</code> aufgerufen wird. Diese Vorbereitung des Adapters enthält das
- Setzen der Zeugnisse (z.B. Benutzername und Passwort) und die Definition von Werten für
- Adapter spezifische Konfigurationoptionen, wie Datenbank Verbindungsdaten für einen Datenbank
- Tabellen Adapter.
- </para>
- <para>
- Das folgende ist ein Beispiel eines Authentifierungs-Adapters der einen Benutzernamen und ein
- Passwort für die Authentifizierung benötigt. Andere Details, wie zum Beispiel der
- Authentifizierungs-Service abgefragt wird, werden der Kürze halber ausgelassen:
- <programlisting role="php"><![CDATA[
- class MyAuthAdapter implements Zend_Auth_Adapter_Interface
- {
- /**
- * Setzt Benutzername und Passwort für die Authentifizierung
- *
- * @return void
- */
- public function __construct($username, $password)
- {
- // ...
- }
- /**
- * Führt einen Authentifizierungs-Versuch durch
- *
- * @throws Zend_Auth_Adapter_Exception Wenn die Authentifizierung nicht
- * durchgeführt wurde
- * @return Zend_Auth_Result
- */
- public function authenticate()
- {
- // ...
- }
- }
- ]]></programlisting>
- Wie im Docblock angegeben, muß <code>authenticate()</code> eine Instanz von
- <classname>Zend_Auth_Result</classname> (oder einer von <classname>Zend_Auth_Result</classname> abgeleiteten Klassen)
- zurückgeben. Wenn aus bestimmten Gründen eine Durchführung einer Authentifizierungs-Anfrage
- nicht möglich ist, sollte <code>authenticate()</code> eine Ausnahme werfen die von
- <classname>Zend_Auth_Adapter_Exception</classname> abgeleitet ist.
- </para>
- </sect2>
- <sect2 id="zend.auth.introduction.results">
- <title>Ergebnisse</title>
- <para>
- <classname>Zend_Auth</classname> Adapter geben eine Instanz von <classname>Zend_Auth_Result</classname> mit Hilfe von
- <code>authenticate()</code> zurück um die Ergebnisse des Authentifizierungs-Versuches darzustellen.
- Adapter veröffentlichen das <classname>Zend_Auth_Result</classname> Objekt bei der Erstellung, so das die
- folgenden vier Methoden ein grundsätzliches Set von Benutzerbezogenen Operationen bieten die
- für die Ergebnisse von <classname>Zend_Auth</classname> Adapter üblich sind:
- <itemizedlist>
- <listitem>
- <para>
- <code>isValid()</code> - Gibt true zurück wenn und nur wenn das Ergebnis einen
- erfolgreichen Authentifizierungs-Versuch repräsentiert
- </para>
- </listitem>
- <listitem>
- <para>
- <code>getCode()</code> - Gibt einen konstanten <classname>Zend_Auth_Result</classname>
- Identifizierer damit der Typ des Authentifizierungs-Fehlers, oder des Erfolgs der
- stattgefunden hat, ermittelt werden kann. Das kann in Situationen verwendet werden
- in denen der Entwickler die verschiedenen Ergebnistypen der Authentifizierung
- unterschiedlich behandeln will. Das erlaubt es dem Entwickler zum Beispiel detailierte
- Statistiken über die Authentifizierungs-Ergebnisse zu erhalten. Eine andere Verwendung
- dieses Features ist es spezielle, benutzerdefinierte Nachrichten anzubieten, um Benutzern
- eine bessere Usability zu ermöglichen, einfach dadurch das Entwickler dazu aufgerufen
- sind die Risiken solche defailierte Informationen Benutzern anzubieten, statt einer
- generellen Nachricht eines Authentifizierungs-Fehlers. Für weitere Informationen siehe
- die Notiz anbei.
- </para>
- </listitem>
- <listitem>
- <para>
- <code>getIdentity()</code> - Gibt die Identität des Authentifizierungs-Versuchs zurück
- </para>
- </listitem>
- <listitem>
- <para>
- <code>getMessages()</code> - Gibt ein Array von Nachrichten zurück nach einem
- fehlgeschlagenen Authentifizierungs-Versuch
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Ein Entwickler kann wünschen basierend auf dem Typ des Authentifizierungs-Ergebnisses zu
- verzweigen um spezialisiertere Operationen durchzuführen. Einige Operationen die für Entwickler
- nützlich sein können sind zum Beispiel das Sperren von Konten nachdem zu oft ein falsches
- Passwort angegeben wurde, das markieren von IP Adressen nachdem zuviele nicht existierende
- Identitäten angegeben wurden und das anbieten von speziellen, benutzerdefinierten Nachrichten
- für Authentifizierungs-Ergebnisse an den Benutzer. Die folgenden Ergebniscodes sind vorhanden:
- <programlisting role="php"><![CDATA[
- Zend_Auth_Result::SUCCESS
- Zend_Auth_Result::FAILURE
- Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
- Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
- Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
- Zend_Auth_Result::FAILURE_UNCATEGORIZED
- ]]></programlisting>
- </para>
- <para>
- Das folgende Beispiel zeigt wie ein Entwickler anhand des Ergebniscodes verzweigen könnte:
- <programlisting role="php"><![CDATA[
- // Innerhalb von AuthController / loginAction
- $result = $this->_auth->authenticate($adapter);
- switch ($result->getCode()) {
- case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
- /** Was wegen nicht existierender Identität machen **/
- break;
- case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
- /** Was wegen ungültigen Zeugnissen machen **/
- break;
- case Zend_Auth_Result::SUCCESS:
- /** Was wegen erfolgreicher Authentifizierung machen **/
- break;
- default:
- /** Was wegen anderen Fehlern machen **/
- break;
- }
- ]]></programlisting>
- </para>
- </sect2>
- <sect2 id="zend.auth.introduction.persistence">
- <title>Dauerhafte Identitäten</title>
- <para>
- Eine Anfrage zu authentifizieren die Authentifizierungs Zeugnisse enthält ist per se nützlich,
- aber auch wichtig um die Authentifizierungs Identität bearbeiten zu können ohne das immer die
- Authentifizierungs Zeugnisse mit jeder Anfrage vorhanden sein müssen.
- </para>
- <para>
- Trotzdem ist HTTP ein statusloses Protokoll, und Techniken wie Cookies und Sessions wurden
- entwickelt um Stati über mehrere Anfragen hinweg in Server-seitigen Web Anwendungen zu
- erhalten.
- </para>
- <sect3 id="zend.auth.introduction.persistence.default">
- <title>Normale Persistenz in PHP Sessions</title>
- <para>
- Standardmäßig bietet <classname>Zend_Auth</classname> dauerhafte Speicherung der Identität eines
- erfolgreichen Authentifizierungs Versuches durch Verwendung der PHP Session. Bei einem
- erfolgreichen Authentifizierungs Versuch speichert <classname>Zend_Auth::authenticate()</classname>
- die Identität des Authentifizierungs Ergebnisses im persistenten Speicher. Solange die
- Konfiguration nicht verändert wird, verwendet <classname>Zend_Auth</classname> eine Speicherklasse
- die <classname>Zend_Auth_Storage_Session</classname> heißt und die im Gegenzug
- <link linkend="zend.session"><classname>Zend_Session</classname></link> verwendet. Eine eigene
- Klasse kann stattdessen verwendet werden, indem ein Objekt an
- <classname>Zend_Auth::setStorage()</classname> übergeben wird welches
- <classname>Zend_Auth_Storage_Interface</classname> implementiert.
- </para>
- <note>
- <para>
- Wenn das automatische persistente Speichern der Identität für einen bestimmten Anwendungsfall
- nicht anwendbar ist, können Entwickler trotzdem die <classname>Zend_Auth</classname> Klasse weiterhin
- verwenden statt direkt eine Adapterklasse anzusprechen.
- </para>
- </note>
- <example id="zend.auth.introduction.persistence.default.example">
- <title>Den Namensraum der Session ändern</title>
- <para>
- <classname>Zend_Auth_Storage_Session</classname> verwendet einen Session Namensraum von
- 'Zend_Auth'. Diese Namensraum kann überschrieben werden indem ein anderer
- Wert an den Konstruktor von <classname>Zend_Auth_Storage_Session</classname> übergeben wird, und dieser
- Wert wird intern an den Konstruktor von <classname>Zend_Session_Namespace</classname> weitergereicht.
- Das sollte vor einem Versuch einer Authentifizierung stattfinden da
- <classname>Zend_Auth::authenticate()</classname> die automatische Speicherung der Identität durchführt.
- <programlisting role="php"><![CDATA[
- // Eine Referenz zur Singleton Instanz von Zend_Auth speichern
- $auth = Zend_Auth::getInstance();
- // 'someNamespace' statt 'Zend_Auth' verwenden
- $auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));
- /**
- * @todo Den Auth Adapter $authAdapter erstellen
- */
- // Authentifizieren, das Ergebnis speichern, und die Identität bei Erfolg
- // persistent machen
- $result = $auth->authenticate($authAdapter);
- ]]></programlisting>
- </para>
- </example>
- </sect3>
- <sect3 id="zend.auth.introduction.persistence.custom">
- <title>Eigene Speicher implementieren</title>
- <para>
- Zeitweise wollen Entwickler einen anderen Speichermechanismus für Identitäten verwenden als
- es von <classname>Zend_Auth_Storage_Session</classname> angeboten wird. Für solche Fälle können
- Entwickler einfach <classname>Zend_Auth_Storage_Interface</classname> implementieren und eine
- Instanz der Klasse an <classname>Zend_Auth::setStorage()</classname> übergeben.
- </para>
- <example id="zend.auth.introduction.persistence.custom.example">
- <title>Eine eigene Speicher Klasse verwenden</title>
- <para>
- Um eine andere Speicherklasse für die Persistenz von Identitäten zu verwenden als sie
- durch <classname>Zend_Auth_Storage_Session</classname> angeboten wird, können Entwickler
- <classname>Zend_Auth_Storage_Interface</classname> implementieren:
- <programlisting role="php"><![CDATA[
- class MyStorage implements Zend_Auth_Storage_Interface
- {
- /**
- * Gibt true zurück wenn und nur wenn der Speicher leer ist
- *
- * @throws Zend_Auth_Storage_Exception Wenn es unmöglich ist festzustellen
- * ob der Speicher leer ist
- * @return boolean
- */
- public function isEmpty()
- {
- /**
- * @todo Implementierung
- */
- }
- /**
- * Gibt den Inhalt des Speichers zurück
- *
- * Das Verhalten ist undefiniert wenn der Speicher leer ist.
- *
- * @throws Zend_Auth_Storage_Exception Wenn das Lesen von Lesen vom Speicher
- * unmöglich ist
- * @return mixed
- */
- public function read()
- {
- /**
- * @todo Implementierung
- */
- }
- /**
- * Schreibt $contents in den Speicher
- *
- * @param mixed $contents
- * @throws Zend_Auth_Storage_Exception Wenn das Schreiben von $contents in
- * den Speicher unmöglich ist
- * @return void
- */
- public function write($contents)
- {
- /**
- * @todo Implementierung
- */
- }
- /**
- * Löscht die Intalte vom Speicher
- *
- * @throws Zend_Auth_Storage_Exception Wenn das Löschen der Inhalte vom
- * Speicher unmöglich ist
- * @return void
- */
- public function clear()
- {
- /**
- * @todo Implementierung
- */
- }
- }
- ]]></programlisting>
- </para>
- <para>
- Um diese selbstgeschriebene Speicherklasse zu verwenden wird
- <classname>Zend_Auth::setStorage()</classname> aufgerufen bevor eine Authentifizierungsanfrage
- stattfindet:
- <programlisting role="php"><![CDATA[
- // Zend_Auth anweisen das die selbstdefinierte Speicherklasse verwendet wird
- Zend_Auth::getInstance()->setStorage(new MyStorage());
- /**
- * @todo Den Auth Adapter $authAdapter erstellen
- */
- // Authentifizieren, das Ergebnis speichern, und die Identität bei Erfolg
- $result = Zend_Auth::getInstance()->authenticate($authAdapter);
- ]]></programlisting>
- </para>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.auth.introduction.using">
- <title>Verwendung</title>
- <para>
- Es gibt zwei vorhandene Wege um <classname>Zend_Auth</classname> Adapter zu verwenden:
- <orderedlist>
- <listitem>
- <para>
- Indirekt durch <classname>Zend_Auth::authenticate()</classname>
- </para>
- </listitem>
- <listitem>
- <para>
- Direkt durch die <code>authenticate()</code> Methode des Adapters
- </para>
- </listitem>
- </orderedlist>
- </para>
- <para>
- Das folgende Beispiel zeigt wie ein <classname>Zend_Auth</classname> Adapter indirekt verwendet
- werden kann, durch die Verwendung der <classname>Zend_Auth</classname> Klasse:
- <programlisting role="php"><![CDATA[
- // Eine Referenz zur Singleton-Instanz von Zend_Auth erhalten
- $auth = Zend_Auth::getInstance();
- // Authentifizierungs Adapter erstellen
- $authAdapter = new MyAuthAdapter($username, $password);
- // Authentifizierungs Versuch, das Ergebnis abspeichern
- $result = $auth->authenticate($authAdapter);
- if (!$result->isValid()) {
- // Authentifizierung fehlgeschlagen; die genauen Gründe ausgeben
- foreach ($result->getMessages() as $message) {
- echo "$message\n";
- }
- } else {
- // Authentifizierung erfolgreich; die Identität ($username) wird in
- // der Session gespeichert
- // $result->getIdentity() === $auth->getIdentity()
- // $result->getIdentity() === $username
- }
- ]]></programlisting>
- </para>
- <para>
- Sobald die Authentifizierung in einer Anfrage durchgeführt wurde, so wie im obigen Beispiel,
- ist es sehr einfach zu Prüfen ob eine erfolgreich authentifizierte Identität existiert:
- <programlisting role="php"><![CDATA[
- $auth = Zend_Auth::getInstance();
- if ($auth->hasIdentity()) {
- // Identität existiert; auslesen
- $identity = $auth->getIdentity();
- }
- ]]></programlisting>
- </para>
- <para>
- Um eine Identität vom persistenten Speicher zu entfernen muß einfach die <code>clearIdentity()</code>
- Methode verwendet werden. Das würde typischerweise für die Implementierung einer "Abmelde" Operation
- in einer Anwendung Verwendung finden.
- <programlisting role="php"><![CDATA[
- Zend_Auth::getInstance()->clearIdentity();
- ]]></programlisting>
- </para>
- <para>
- Wenn die automatische Verwendung von persistenten Speichern für einen bestimmten Verwendungszweck
- unangebracht ist, kann ein Entwickler einfach die Verwendung der <classname>Zend_Auth</classname> Klasse
- umgehen, und eine Adapter Klasse direkt verwenden. Die direkte Verwendung einer Adapterklasse
- enthält das Konfigurieren und Vorbereiten eines Adapter Objektes und den Aufruf dessen
- <code>authenticate()</code> Methode. Adapter-spezifische Details werden in der Dokumentation
- jeden Adapters besprochen. Das folgende Beispeil verwendet <code>MyAuthAdapter</code> direkt:
- <programlisting role="php"><![CDATA[
- // Den Authentifizierungs Adapter erstellen
- $authAdapter = new MyAuthAdapter($username, $password);
- // Authentifizierungs Versuch, speichere das Ergebnis
- $result = $authAdapter->authenticate();
- if (!$result->isValid()) {
- // Authentifizierung fehlgeschlagen; die genauen Gründe ausgeben
- foreach ($result->getMessages() as $message) {
- echo "$message\n";
- }
- } else {
- // Authentifizierung erfolgreich
- // $result->getIdentity() === $username
- }
- ]]></programlisting>
- </para>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|