<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 14978 -->
<!-- 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:
-->