<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.auth.adapter.ldap">
    <title>LDAP Authentifizierung</title>

    <sect2 id="zend.auth.adapter.ldap.introduction">
        <title>Einführung</title>

        <para>
            <classname>Zend_Auth_Adapter_Ldap</classname> unterstützt Webanwendungen bei der
            Authentifizierung mit <acronym>LDAP</acronym> Services. Die Features beinhalten
            Kanonisierung von Benutzernamen und Domainnamen, Mehrfach-Domain Authentifizierung, und
            Fehlerbehandlungs Features. Es wurde getestet mit <ulink
                url="http://www.microsoft.com/windowsserver2003/technologies/directory/activedirectory/">Microsoft
                Active Directory</ulink> und <ulink url="http://www.openldap.org/">OpenLDAP</ulink>,
            sollte auch mit anderen <acronym>LDAP</acronym> Service Provider zusammenarbeiten.
        </para>

        <para>
            Diese Dokumentation enthält eine Anleitung der Verwendung von
            <classname>Zend_Auth_Adapter_Ldap</classname>, eine Beschreibung der
            <acronym>API</acronym>, eine Ausgabe der verschiedenen Optionen, Diagnostische
            Informationen für die Fehlerbehandlung bei Authentifizierungs Problemen, und Beispiel
            Optionen für beide, Active Directory und OpenLDAP Server.
        </para>
    </sect2>

    <sect2 id="zend.auth.adapter.ldap.usage">
        <title>Verwendung</title>

        <para>
            Um <classname>Zend_Auth_Adapter_Ldap</classname> Authentifizierung in eigene Anwendungen
            schnell einzubauen, selbst wenn <classname>Zend_Controller</classname> nicht verwendet
            wird, sollte das Fleisch des eigenen Codes in etwa wie folgt aussehen:
        </para>

        <programlisting language="php"><![CDATA[
$username = $this->_request->getParam('username');
$password = $this->_request->getParam('password');

$auth = Zend_Auth::getInstance();

$config = new Zend_Config_Ini('../application/config/config.ini',
                              'production');
$log_path = $config->ldap->log_path;
$options = $config->ldap->toArray();
unset($options['log_path']);

$adapter = new Zend_Auth_Adapter_Ldap($options, $username,
                                      $password);

$result = $auth->authenticate($adapter);

if ($log_path) {
    $messages = $result->getMessages();

    $logger = new Zend_Log();
    $logger->addWriter(new Zend_Log_Writer_Stream($log_path));
    $filter = new Zend_Log_Filter_Priority(Zend_Log::DEBUG);
    $logger->addFilter($filter);

    foreach ($messages as $i => $message) {
        if ($i-- > 1) { // $messages[2] und höher sind Log Nachrichten
            $message = str_replace("\n", "\n  ", $message);
            $logger->log("Ldap: $i: $message", Zend_Log::DEBUG);
        }
    }
}
]]></programlisting>

        <para>
            Natürlich ist der Logging Code optional, aber es wird dringend empfohlen einen Logger
            zu verwenden. <classname>Zend_Auth_Adapter_Ldap</classname> zeichnet fast jedes
            Bisschen an Information in <varname>$messages</varname> auf das irgendwer benötigen
            können (mehr anbei), was allerdings selbst ein nettes Feature für jemanden als History
            ist, kann überaus schwierig zu debuggen sein.
        </para>

        <para>
            Der <classname>Zend_Config_Ini</classname> wird oben verwendet um die Optionen des
            Adapters zu laden. Er ist also auch optional. Ein reguläres Array würde genauso gut
            arbeiten. Das folgende ist eine Beispiel
            <filename>application/config/config.ini</filename> Datei die Optionen für zwei separate
            Server hat. Mit mehreren Sets von Server Optionen versucht der Adapter jede in
            Reihenfolge bis die Zugangsdaten erfolgreich authentifiziert wurden. Die Namen der
            Server (z.B., 'server1' und 'server2') sind sehr verallgemeinert. Für Details
            betreffend dem Array für Optionen, siehe das Kapitel über <emphasis>Server
                Optionen</emphasis> weiter unten. Es ist zu beachten das
            <classname>Zend_Config_Ini</classname> jeden Wert der mit Gleichheitszeichen
            (<emphasis>=</emphasis>) geschrieben wird auch unter Anführungszeichen gesetzt wird
            (wie unten bei DNs gezeigt).
        </para>

        <programlisting language="ini"><![CDATA[
[production]

ldap.log_path = /tmp/ldap.log

; Typische Optionen für OpenLDAP
ldap.server1.host = s0.foo.net
ldap.server1.accountDomainName = foo.net
ldap.server1.accountDomainNameShort = FOO
ldap.server1.accountCanonicalForm = 3
ldap.server1.username = "CN=user1,DC=foo,DC=net"
ldap.server1.password = pass1
ldap.server1.baseDn = "OU=Sales,DC=foo,DC=net"
ldap.server1.bindRequiresDn = true

; Typische Optionen für Active Directory
ldap.server2.host = dc1.w.net
ldap.server2.useStartTls = true
ldap.server2.accountDomainName = w.net
ldap.server2.accountDomainNameShort = W
ldap.server2.accountCanonicalForm = 3
ldap.server2.baseDn = "CN=Users,DC=w,DC=net"
]]></programlisting>

        <para>
            Die obige Konfiguration instruiert <classname>Zend_Auth_Adapter_Ldap</classname> das es
            versuchen soll Benutzer zuerst mit dem OpenLDAP Server <filename>s0.foo.net</filename>
            authentifizieren soll. Wenn die Authentifizierung auf irgendeinem Grund fehlschlägt,
            wird der AD Server <filename>dc1.w.net</filename> versucht.
        </para>

        <para>
            Mit Servern in verschiedenen Domains, zeigt diese Konfiguration Multi-Domain
            Authentifizierung. Es können auch mehrere Server in der gleichen Domain sein um
            Redundanz anzubieten.
        </para>

        <para>
            In diesem Fall ist zu beachten das, selbst wenn OpenLDAP keine Notwendigkeit für kurze
            NetBIOS Stil Domainnamen hat die von Windows verwendet werden bieten wir Sie hier an
            wegen der Kanonifizierung der Namen (beschrieben im
            <emphasis>Kanonifizierung von Benutzernamen</emphasis> Kapitel anbei).
        </para>
    </sect2>

    <sect2 id="zend.auth.adapter.ldap.api">
        <title>Die API</title>

        <para>
            Der <classname>Zend_Auth_Adapter_Ldap</classname> Konstruktor akzeptiert drei Parameter.
        </para>

        <para>
            Der <varname>$options</varname> Parameter wird benötigt und muß ein Array sein das ein
            oder mehrere Sets von Optionen enthält. Es ist zu beachten das es sich um
            <emphasis>Array von Arrays</emphasis> von <link
                linkend="zend.ldap"><classname>Zend_Ldap</classname></link> Optionen handelt. Selbst
            wenn nur ein einzelner <acronym>LDAP</acronym> Server verwendet wird, müssen die
            Optionen trotzdem in einem anderen Array sein.
        </para>

        <para>
            Anbei ist eine <ulink
                url="http://php.net/print_r"><methodname>print_r()</methodname></ulink>
            Ausgabe von beispielhaften Optionsparameters die zwei Sets von Serveroptionen für
            <acronym>LDAP</acronym> Server enthalten, <filename>s0.foo.net</filename> und
            <filename>dc1.w.net</filename> (die gleichen Optionen wie in der oberen
            <acronym>INI</acronym> Repräsentation):
        </para>

        <programlisting language="output"><![CDATA[
Array
(
    [server2] => Array
        (
            [host] => dc1.w.net
            [useStartTls] => 1
            [accountDomainName] => w.net
            [accountDomainNameShort] => W
            [accountCanonicalForm] => 3
            [baseDn] => CN=Users,DC=w,DC=net
        )

    [server1] => Array
        (
            [host] => s0.foo.net
            [accountDomainName] => foo.net
            [accountDomainNameShort] => FOO
            [accountCanonicalForm] => 3
            [username] => CN=user1,DC=foo,DC=net
            [password] => pass1
            [baseDn] => OU=Sales,DC=foo,DC=net
            [bindRequiresDn] => 1
        )

)
]]></programlisting>

        <para>
            Die oben angebotene Information in jedem Set von Optionen ist hauptsächlich deswegen
            unterschiedlich weil AD keinen Benutzernamen während des Bindesn in der DN Form benötigt
            (siehe die <property>bindRequiresDn</property> Option des
            <emphasis>Server Optionen</emphasis> Kapitels weiter unten), was bedeutet das die
            Anzahl der, mit dem Empfangen der DN, für einen Benutzernamen der Authentifiziert
            werden soll, assoziierten Optionen, unterdrückt werden kann.
        </para>

        <note>
            <title>Was ist ein ausgezeichneter Name?</title>

            <para>
                Ein DN oder "distinguished name" ist ein String der den Pfad zu einem Objekt im
                <acronym>LDAP</acronym> Verzeichnis repräsentiert. Jede komma-seperierte Komponente
                ist ein Attribut und Wert der einen Node repräsentiert. Die Komponenten werden
                rückwirkend evaluiert. Zum Beispiel ist der Benutzeraccount
                <emphasis>CN=Bob Carter,CN=Users,DC=w,DC=net</emphasis> direkt in
                <emphasis>CN=Users,DC=w,DC=net container</emphasis> enthalten. Diese Struktur wird
                am besten mit einem <acronym>LDAP</acronym> Browser wie das <acronym>ADSI</acronym>
                Edit <acronym>MMC</acronym> snap-in für Active Directory oder phpLDAPadmin erkundet.
            </para>
        </note>

        <para>
            Die Namen von Servern (z.B. 'server1' und 'server2' wie unten gezeigt) sind großteils
            beliebig, aber aus Gründen der Verwendung von <classname>Zend_Config</classname>
            sollten die Identifikatoren (im Gegensatz dazu das Sie nummerische Indezes sind)
            vorhanden sein, und sollten keine spezielle Zeichen enthalten die vom assoziierten
            Dateiformat verwendet werden (z.B. der '<emphasis>.</emphasis>' <acronym>INI</acronym>
            Eigenschafts Separator, '<emphasis>&amp;</emphasis>' für <acronym>XML</acronym> Entity
            Referenzen, usw.).
        </para>

        <para>
            Mit mehreren Sets von Serveroptionen, kann der Adapter Benutzer in mehreren Domains
            authentifizieren und bietet ein Failover damit, wenn ein Server nicht erreichbar ist,
            ein anderer abgefragt wird.
        </para>

        <note>
            <title>Die glorreichen Details: Was passiert bei der Authentifizierungs Methode?</title>

            <para>
                Wenn die <methodname>authenticate()</methodname> Methode aufgerufen wird, iteriert
                der Adapter über jedes Set von Serveroptione, setzt diese auf der internen
                <classname>Zend_Ldap</classname> Instanz und ruft die
                <methodname>Zend_Ldap::bind()</methodname> Methode, mit dem Benutzernamen und
                Passwort das authentifiziert werden soll, auf. Die <classname>Zend_Ldap</classname>
                Klasse prüft um zu sehen ob der Benutzer mit einer Domain qualifiziert ist (hat
                z.B. eine Domainkomponente wie <filename>alice@foo.net</filename> oder
                <filename>FOO\alice</filename>). Wenn eine Domain vorhanden ist, aber mit keiner
                der Domainnamen der Server (<filename>foo.net</filename> oder
                <acronym>FOO</acronym>) übereinstimmt, wird eine spezielle Ausnahme geworfen und
                durch <classname>Zend_Auth_Adapter_Ldap</classname> gefangen, was bewirkt das der
                Server ignoriert wird und der nächste, in den Serveroptionen gesetzte Server,
                ausgewählt wird. Wenn eine Domain <emphasis>doch</emphasis> passt, oder der
                Benutzer keinen qualifizierten Benutzernamen angegeben hat, fährt
                <classname>Zend_Ldap</classname> weiter fort und versucht mit den angegebenen
                Zugangsdaten zu binden. Wenn das Binden nicht erfolgreich war wirft
                <classname>Zend_Ldap</classname> eine <classname>Zend_Ldap_Exception</classname>
                welche durch <classname>Zend_Auth_Adapter_Ldap</classname> gefangen wird, und das
                nächste Set von Serveroptionen wird versucht. Wenn das Binden erfolgreich war, wird
                die Iteration gestoppt, und die <methodname>authenticate()</methodname> Methode des
                Adapters gibt ein erfolgreiches Ergebnis zurück. Wenn alle Serveroptionen ohne
                Erfolg durchprobiert wurden, schlägt die Authentifizierung fehl, und
                <methodname>authenticate()</methodname> gibt ein Fehlerergebnis zurück mit der
                Fehlermeldung der letzten Iteration.
            </para>
        </note>

        <para>
            Die username und password Parameter des <classname>Zend_Auth_Adapter_Ldap</classname>
            Konstruktors repräsentieren die Zugangsdaten die authentifiziert werden sollen (z.B.
            die Zugangsdaten die durch den Benutzer über eine <acronym>HTML</acronym> Login Form
            angegeben werden). Alternativ können Sie auch mit den
            <methodname>setUsername()</methodname> und <methodname>setPassword()</methodname>
            Methoden gesetzt werden.
        </para>
    </sect2>

    <sect2 id="zend.auth.adapter.ldap.server-options">
        <title>Server Optionen</title>

        <para>
            Jedes Set von Serveroptionen <emphasis>im Kontext von
            <classname>Zend_Auth_Adapter_Ldap</classname></emphasis> besteht aus den folgenden
            Optionen welche, großteils ungeändert, an
            <methodname>Zend_Ldap::setOptions()</methodname> übergeben werden:
        </para>

        <table id="zend.auth.adapter.ldap.server-options.table">
            <title>Server Optionen</title>

            <tgroup cols="2">
                <thead>
                    <row>
                        <entry>Name</entry>
                        <entry>Beschreibung</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry><emphasis><property>host</property></emphasis></entry>

                        <entry>
                            Der Hostname des <acronym>LDAP</acronym> Servers der diese Optionen
                            repräsentiert. Diese Option wird benötigt.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>port</property></emphasis></entry>

                        <entry>
                            Der Port auf den der <acronym>LDAP</acronym> Server schaut. Wenn
                            <emphasis>useSsl</emphasis> <constant>TRUE</constant> ist, ist der
                            Standardwert von <property>port</property> 636. Wenn
                            <property>useSsl</property> <constant>FALSE</constant> ist, ist der
                            Standardwert von <property>port</property> 389.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>useStartTls</property></emphasis></entry>

                        <entry>
                            Ob der <acronym>LDAP</acronym> Client einen <acronym>TSL</acronym> (aka
                            <acronym>SSL</acronym>v2) verschlüsselten Transport verwenden soll oder
                            nicht. Der Wert <constant>TRUE</constant> wird in einer
                            Produktionsumgebung strengstens empfohlen um zu verhindern das
                            Passwörter im Klartext übertragen werden. Der Standardwert ist
                            <constant>FALSE</constant>, da Server typischerweise nach deren
                            Installation erwarten das ein Zertifikat installiert wird. Die
                            <property>useSsl</property> und <property>useStartTls</property>
                            Optionen schließen sich gegenseitig aus. Die
                            <property>useStartTls</property> Option sollte über
                            <property>useSsl</property> favorisiert werden, aber nicht alle Server
                            unterstützen diesen neueren Mechanismus.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>useSsl</property></emphasis></entry>

                        <entry>
                            Ob der <acronym>LDAP</acronym> Client einen <acronym>SSL</acronym>
                            verschlüsselten Transport verwenden soll. Die
                            <property>useSsl</property> und <property>useStartTls</property>
                            Optionen schließen sich gegenseitig aus, aber
                            <property>useStartTls</property> sollte favorisiert werden wenn der
                            Server und die <acronym>LDAP</acronym> Bibliothek des Clients diese
                            unterstützen. Dieser Wert ändert auch den Standardwert von
                            <property>port</property> (siehe die <property>port</property>
                            Beschreibung weiter oben).
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>username</property></emphasis></entry>

                        <entry>
                            Der DN des Accounts der verwendet wird um DN Account Loopups
                            durchzuführen. <acronym>LDAP</acronym> Server die den Benutzernamen
                            in DN Form benötigen wenn "bind" durchgeführt wird, benötigen diese
                            Option. Wenn <property>bindRequiresDn</property>
                            <constant>TRUE</constant> ist, wird diese Option benötigt. Dieser
                            Account muß kein privilegierter Account sein - ein Account mit nur-lese
                            Zugriff zu Objekten unter <property>baseDn</property> ist alles was
                            notwendig ist (und bevorzugt unter dem <emphasis>Prinzip des geringsten
                            Privilegs</emphasis>).
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>password</property></emphasis></entry>

                        <entry>
                            Das Passwort des Accounts der verwendet wird um DN Lookups
                            durchzuführen. Wenn diese Option nicht unterstützt wird, versucht der
                            <acronym>LDAP</acronym> Client einen "anonymen bind" wenn DN Lookups
                            durchgeführt werden.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>bindRequiresDn</property></emphasis></entry>

                        <entry>
                            Einige <acronym>LDAP</acronym> Server benötigen den zum Binden
                            verwendeten Benutzernamen in der DN Form wie
                            <emphasis>CN=Alice Baker,OU=Sales,DC=foo,DC=net</emphasis>
                            (grundsätzlich alle Server <emphasis>außer</emphasis> AD). Wenn diese
                            Option <constant>TRUE</constant> ist, instuiert dies
                            <classname>Zend_Ldap</classname> das der DN automatisch empfangen wird,
                            abhängig vom Benutzernamen der authentifiziert wird, wenn er nicht
                            bereits in DN Form ist, und diesen dann wieder mit der richtigen DN zu
                            binden. Der Standardwert ist <constant>FALSE</constant>. Aktuell ist nur
                            von Microsoft Active Directory Server (<acronym>ADS</acronym>) bekannt
                            das es den Benutzernamen <emphasis>nicht</emphasis> in der DN Form
                            benötigt wenn gebunden wird, und deswegen kann diese Option mit AD auch
                            <constant>FALSE</constant> sein (und sollte das auch, da das Empfangen
                            des DN eine extra Anfrage zum Server benötigt). Andernfalls muß diese
                            Option auf <constant>TRUE</constant> gesetzt werden (z.B. für OpenLDAP).
                            Diese Option kontrolliert das Standard
                            <property>acountFilterFormat</property> das verwendet wird wenn nach
                            Accounts gesucht wird. Siehe auch die
                            <property>accountFilterFormat</property> Option.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>baseDn</property></emphasis></entry>

                        <entry>
                            Der Ort vom DN unter dem alle Accounts die authentifiziert werden. Diese
                            Option wird benötigt. Wenn man sich unsicher über den richtigen
                            <property>baseDn</property> ist, sollte es genug sein Ihn von
                            der <acronym>DNS</acronym> Domain des Benutzers der die
                            <emphasis>DC=</emphasis> Komponenten verwedet abzuleiten. Wenn der
                            Hauptname eines Benutzers <filename>alice@foo.net</filename> ist, sollte
                            ein <property>baseDn</property> von <emphasis>DC=foo,DC=net</emphasis>
                            funktionieren. Eine präzisere Ortsangabe
                            (z.B. <emphasis>OU=Sales,DC=foo,DC=net</emphasis>) ist trotzdem
                            effizienter.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>accountCanonicalForm</property></emphasis></entry>

                        <entry>
                            Ein Wert von 2, 3 oder 4 zeigt die Form zu der Account Namen
                            authorisiert werden sollten nachdem die Authentifizierung erfolgreich
                            war. Die Werte sind wie folgt: 2 für traditionelle Benutzernamen-Stil
                            Namen (z.B., <emphasis>alice</emphasis>), 3 für Schrägstrich-Stil Namen
                            (z.B., <filename>FOO\alice</filename>) oder 4 für Authentifiziert-Sil
                            Namen (z.B., <filename>alice@foo.net</filename>). Der Standardwert ist 4
                            (z.B., <filename>alice@foo.net</filename>). Mit einem Wert von 3, z.B.,
                            wird die Identität die von
                            <methodname>Zend_Auth_Result::getIdentity()</methodname> zurückgegeben
                            wird (und <methodname>Zend_Auth::getIdentity()</methodname>, wenn
                            <classname>Zend_Auth</classname> verwendet wird), immer
                            <filename>FOO\alice</filename> sein, unabhängig von der Form in der
                            Alice angegeben wurde, egal ob es <emphasis>alice</emphasis>,
                            <filename>alice@foo.net</filename>, <filename>FOO\alice</filename>,
                            <filename>FoO\aLicE</filename>, <filename>foo.net\alice</filename>, etc.
                            Siehe das Kapitel <emphasis>Kanonisierung von Account Namen</emphasis>
                            in der <classname>Zend_Ldap</classname> Dokumentation für Details. Bei
                            der Verwendung von mehreren Sets von Serveroptionen ist es
                            empfehlenswert, aber nicht notwendig, das die selbe
                            <property>accountCanonicalForm</property> in allen
                            Serveroptionen verwendet wird, sodas die sich ergebenden Benutzernamen
                            immer auf die selbe Art und Weise kanonisiert werden (z.b. wenn man auf
                            <filename>EXAMPLE\username</filename> mit einem AD Server kanonisiert,
                            aber zu <filename>username@example.com</filename> mit einem OpenLDAP
                            Server, kann das quirks für die High-Level Logik einer Anwendung sein).
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>accountDomainName</property></emphasis></entry>

                        <entry>
                            Der <acronym>FQDN</acronym> Domainname für welchen der Ziel
                            <acronym>LDAP</acronym> Server eine Authorität ist (z.B.,
                            <filename>example.com</filename>). Diese Option wird verwendet um Namen
                            zu kanonisieren sodas der Benutzername der vom Benutzer angeboten wird,
                            wie es für das Binden notwendig ist, konvertiert werden kann. Er wird
                            auch verwendet um festzustellen ob der Server eine Authorität für den
                            angegebenen Benutzernamen ist (z.B., wenn
                            <property>accountDomainName</property> <filename>foo.net</filename> ist
                            und der angegebene Benutzer <filename>bob@bar.net</filename>, wird der
                            Server nicht abgefragt, und das Ergebnis wird ein Fehler sein). Diese
                            Option wird nicht benötigt, aber wenn Sie nicht angegeben wird, dann
                            werden Benutzernamen in prinzipieller Namensform (z.B.,
                            <filename>alice@foo.net</filename>) nicht unterstützt. Es wird stark
                            empfohlen das diese Option angegeben wird, da es viele Anwendungsfälle
                            gibt welche die Erstellung von prinzipieller Namensform benötigen.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>accountDomainNameShort</property></emphasis></entry>

                        <entry>
                            Die 'short' Domain für die der Ziel <acronym>LDAP</acronym> Server eine
                            Authorität ist (z.B., <acronym>FOO</acronym>). Es ist z ubeachten das
                            es ein 1:1 Mapping zwischen <property>accountDomainName</property> und
                            <property>accountDomainNameShort</property> existiert. Diese
                            Option sollte verwendet werden um den NetBIOS Domainnamen für Windows
                            Netzwerke zu spezifizieren, kann aber auch von nicht-AD Servern
                            verwendet werden (z.B., für Konsistenz bei mehreren Sets von
                            Serveroptionen bei dem Schrägstrich Stil
                            <property>accountCanonicalForm</property>). Diese Option wird nicht
                            benötigt, aber wenn Sie nicht angegeben wird, werden Benutzernamen im
                            Schrägstrich Stil (z.B. <filename>FOO\alice</filename>) nicht
                            unterstützt.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>accountFilterFormat</property></emphasis></entry>

                        <entry>
                            Der <acronym>LDAP</acronym> Suchfilter der für die Suche nach Accounts
                            verwendet wird. Dieser String ist ein <ulink
                                url="http://php.net/printf"><methodname>printf()</methodname></ulink>-Stil
                            Ausdruck der ein '<emphasis>%s</emphasis>' enthalten muß um den
                            Benutzernamen unterzubringen. Der Standardwert ist
                            '<emphasis>(&amp;(objectClass=user)(sAMAccountName=%s))</emphasis>',
                            ausgenommen <property>bindRequiresDn</property> wird auf
                            <constant>TRUE</constant> gesetzt. In diesem Fall ist der Standardwert
                            '<emphasis>(&amp;(objectClass=posixAccount)(uid=%s))</emphasis>'. Wenn,
                            zum Beispiel, aus irgendeinem Grund
                            <emphasis>bindRequiresDn = true</emphasis> mit AD verwendet werden soll,
                            muß <emphasis>accountFilterFormat =
                                '(&amp;(objectClass=user)(sAMAccountName=%s))</emphasis>' gesetzt
                            werden.
                        </entry>
                    </row>

                    <row>
                        <entry><emphasis><property>optReferrals</property></emphasis></entry>

                        <entry>
                            Wenn sie auf <constant>TRUE</constant> gesetzt wird, zeigt diese Option
                            dem <acronym>LDAP</acronym> Client an, das Referenzen gefolgt werden
                            soll. Der Standardwert ist <constant>FALSE</constant>.
                        </entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <note>
            <para>
                Wenn <emphasis>useStartTls = <constant>TRUE</constant></emphasis> oder
                <emphasis>useSsl = <constant>TRUE</constant></emphasis> aktiviert ist, erzeugt der
                <acronym>LDAP</acronym> Client einen Fehler der aussagt das er das Zertifikat des
                Servers nicht überprüfen kann. Angenommen die <acronym>PHP</acronym>
                <acronym>LDAP</acronym> Erweiterung ist ultimativ verlinkt mit der OpenLDAP Client
                Bibliothek, muß man um dieses Problem zu lösen
                "<command>TLS_REQCERT never</command>" im OpenLDAP Client
                <filename>ldap.conf</filename> setzen (und den Web Server restarten) um der
                OpenLDAP Client Bibliothek anzuzeigen das man dem Server vertraut. Alternativ,
                wenn man annimmt das der Server gehackt werden könnte kann das Basiszertifikat des
                <acronym>LDAP</acronym> Servers exportiert und auf den Webserver gegeben werden so
                dass der OpenLDAP Client die Identität des Servers prüfen kann.
            </para>
        </note>
    </sect2>

    <sect2 id="zend.auth.adapter.ldap.debugging">
        <title>Debug Nachrichten sammeln</title>

        <para>
            <classname>Zend_Auth_Adapter_Ldap</classname> sammelt Debug Informationen in seiner
            <methodname>authenticate()</methodname> Methode. Diese Information wird im
            <classname>Zend_Auth_Result</classname> Objekt als Nachrichten gespeichert. Das von
            <methodname>Zend_Auth_Result::getMessages()</methodname> zurückgegebene Array kann wie
            folgt beschrieben werden:
        </para>

        <table id="zend.auth.adapter.ldap.debugging.table">
            <title>Debug Nachrichten</title>

            <tgroup cols="2">
                <thead>
                    <row>
                        <entry>Array Index der Nachricht</entry>
                        <entry>Beschreibung</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry>Index 0</entry>

                        <entry>
                            Eine generelle, Benutzerfreundliche Meldung die für die Anzeige für
                            Benutzer passt (z.B. "Ungültige Anmeldedaten"). Wenn die
                            Authentifizierung erfolgreich ist, dann ist dieser String leer.
                        </entry>
                    </row>

                    <row>
                        <entry>Index 1</entry>

                        <entry>
                            Eine detailiertere Fehlermeldung die nicht für die Anzeige für Benutzer
                            hergenommen werden kann, die aber mitgeloggt werden sollte zum Vorteil
                            des Server Operators. Wenn die Authentifizierung erfolgreich war, ist
                            dieser String leer.
                        </entry>
                    </row>

                    <row>
                        <entry>Indezes 2 und höher</entry>
                        <entry>Alle Logmeldungen in Reihenfolge starten bei Index 2.</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <para>
            Aus der Praxis heraus sollte der Index 0 dem Benutzer angezeigt werden (z.B. bei
            Verwendung des FlashMessenger Helfers), Index 1 sollte geloggt werden und, wenn die
            Debugging Information gesammelt wird, sollten die Indezes 2 und höher auch geloggt
            werden (auch wenn die letzte Nachricht immer den String vom Index 1 enthält).
        </para>
    </sect2>

    <sect2 id="zend.auth.adapter.ldap.options-common-server-specific">
        <title>Übliche Optionen für spezielle Server</title>

        <sect3 id="zend.auth.adapter.ldap.options-common-server-specific.active-directory">
            <title>Optionen für Active Directory</title>

            <para>
                Für <acronym>ADS</acronym> sind die folgenden Optionen beachtenswert:
            </para>

            <table
                id="zend.auth.adapter.ldap.options-common-server-specific.active-directory.table">
                <title>Optionen für Active Directory</title>

                <tgroup cols="2">
                    <thead>
                        <row>
                            <entry>Name</entry>
                            <entry>Zusätzliche Notizen</entry>
                        </row>
                    </thead>

                    <tbody>
                        <row>
                            <entry><emphasis><property>host</property></emphasis></entry>
                            <entry>Wie bei allen Servern, wird diese Option benötigt.</entry>
                        </row>

                        <row>
                            <entry><emphasis><property>useStartTls</property></emphasis></entry>

                            <entry>
                                Zum Zwecke der Sicherheit, sollte das <constant>TRUE</constant> sein
                                wenn der Server das notwendige Zertifikat installiert hat.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>useSsl</property></emphasis></entry>

                            <entry>
                                Möglicherweise als Alternative zu <emphasis>useStartTls</emphasis>
                                zu verwenden (siehe davor).
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>baseDn</property></emphasis></entry>

                            <entry>
                                Wie bei allen Servern, wird diese Option benötigt. Standardmäßig
                                platziert AD alle Benutzer Accounts unter dem
                                <emphasis>Users</emphasis> Container (z.B.,
                                <emphasis>CN=Users,DC=foo,DC=net</emphasis>), aber der Standard ist
                                in größeren Organisationen nicht üblich. Der AD Administrator sollte
                                nach der besten DN für Accounts für die eigene Anwendung gefragt
                                werden.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>accountCanonicalForm</property></emphasis></entry>

                            <entry>
                                Das wird man normalerweise für Schrägstrich-Stil Namen auf 3 stellen
                                (z.B., <filename>FOO\alice</filename>), was für Windows Benutzer am
                                bekanntesten ist. Man sollte <emphasis>nicht</emphasis> die
                                unqualifizierte Form 2 verwenden (z.B., <emphasis>alice</emphasis>),
                                da das anderen Benutzern Zugriff auf die Anwendung geben würde, wenn
                                Sie den gleichen Benutzernamen in anderen vertrauten Domains haben
                                (z.B., <filename>BAR\alice</filename> und
                                <filename>FOO\alice</filename> würden als der gleiche Benutzer
                                behandelt). (siehe auch die Notiz anbei.)
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>accountDomainName</property></emphasis></entry>

                            <entry>
                                Das wird mit AD benötigt, ausser
                                <property>accountCanonicalForm</property> 2 wird
                                verwendet, was wiederum nicht eingesetzt werden sollte.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>accountDomainNameShort</property></emphasis></entry>

                            <entry>
                                Der NetBIOS Name der Domain in der die Benutzer sind und für den der
                                AD Server die Authorität ist. Das wird benötigt wenn der
                                Schrägstrich-Stil <property>accountCanonicalForm</property>
                                verwendet wird.
                            </entry>
                        </row>
                    </tbody>
                </tgroup>
            </table>

            <note>
                <para>
                    Technisch sollte es keine Probleme mit irrtümlichen Domain-übergreifenden
                    Authentifizierungen mit der aktuellen
                    <classname>Zend_Auth_Adapter_Ldap</classname> Implementation geben, da
                    Serverdomains explizit geprüft werden, aber das muss für zukünftige
                    Implementationen, welche die Domain während der Laufzeit ermitteln, nicht wahr
                    sein, oder auch wenn ein alternativer Adapter verwendet wird (z.B., Kerberos).
                    Generell ist bekannt das die Mehrdeutigkeit von Accountnamen ein
                    Sicherheitsproblem ist. Man sollte deswegen immer versuchen qualifizierte
                    Accountnamen zu verwenden.
                </para>
            </note>
        </sect3>

        <sect3 id="zend.auth.adapter.ldap.options-common-server-specific.openldap">
            <title>Optionen für OpenLDAP</title>

            <para>
                Für OpenLDAP oder einen generellen <acronym>LDAP</acronym> Server der ein typisches
                posixAccount Stil Schema verwendet sind die folgenden Optionen beachtenswert:
            </para>

            <table id="zend.auth.adapter.ldap.options-common-server-specific.openldap.table">
                <title>Optionen für OpenLDAP</title>

                <tgroup cols="2">
                    <thead>
                        <row>
                            <entry>Name</entry>
                            <entry>Zusätzliche Notizen</entry>
                        </row>
                    </thead>

                    <tbody>
                        <row>
                            <entry><emphasis><property>host</property></emphasis></entry>
                            <entry>Wie bei allen Servern, wird diese Option benötigt.</entry>
                        </row>

                        <row>
                            <entry><emphasis><property>useStartTls</property></emphasis></entry>

                            <entry>
                                Zum Zwecke der Sicherheit, sollte das <constant>TRUE</constant> sein
                                wenn der Server das notwendige Zertifikat installiert hat.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>useSsl</property></emphasis></entry>

                            <entry>
                                Möglicherweise als Alternative zu <property>useStartTls</property>
                                zu verwenden (siehe davor).
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>username</property></emphasis></entry>

                            <entry>
                                Benötigt und muß ein DN sein, da OpenLDAP den Benutzernamen in DN
                                Form benötigt wenn ein Binden durchgeführt wird. Es sollte versucht
                                werden einen nicht privilegierten Account zu verwenden.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>password</property></emphasis></entry>

                            <entry>
                                Das Passwort das zum Benutzernamen von oben gehört. Es kann aber
                                unterdrückt werden wenn der <acronym>LDAP</acronym> Server anonymes
                                Binden bei Abfragen zu Benutzer Accounts erlaubt.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>bindRequiresDn</property></emphasis></entry>

                            <entry>
                                Benötigt und muß <constant>TRUE</constant> sein, da OpenLDAP den
                                Benutzernamen in DN Form benötigt wenn ein Binden durchgeführt wird.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>baseDn</property></emphasis></entry>

                            <entry>
                                Wie bei allen Servern, wird diese Option benötigt und zeigt den DN
                                in dem alle Accounts die authentifiziert werden enthalten sind.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>accountCanonicalForm</property></emphasis></entry>

                            <entry>
                                Optional, aber der Standardwert ist 4 (prinzipielle-Stil Namen wie
                                <filename>alice@foo.net</filename>) und könnte für die Benutzer
                                nicht ideal sein wenn diese Schrägstrich-Stil Namen verwendetn
                                (z.B., <filename>FOO\alice</filename>). Für Schrägstrich-Stil Namen
                                sollte der Wert 3 verwendet werden.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>accountDomainName</property></emphasis></entry>

                            <entry>
                                Benötigt es sei denn man verwendet
                                <property>accountCanonicalForm</property> 2, was nicht
                                zu empfehlen ist.
                            </entry>
                        </row>

                        <row>
                            <entry><emphasis><property>accountDomainNameShort</property></emphasis></entry>

                            <entry>
                                Wenn AD auch nicht verwendet wird, wird dieser Wert nicht benötigt.
                                Andernfalls, wenn
                                <property>accountCanonicalForm</property> 3 verwendet
                                wird, wird diese Option benötigt und sollte ein Kurzname sein der
                                adäquat zu <property>accountDomainName</property>
                                korrespondiert (z.B., wenn
                                <property>accountDomainName</property>
                                <filename>foo.net</filename> ist, wäre ein guter
                                <property>accountDomainNameShort</property> Wert
                                <acronym>FOO</acronym>).
                            </entry>
                        </row>
                    </tbody>
                </tgroup>
            </table>
        </sect3>
    </sect2>
</sect1>
