| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.ldap.introduction">
- <title>Einführung</title>
- <para>
- <classname>Zend_Ldap</classname> ist eine Klasse, mit der <acronym>LDAP</acronym>
- Operationen, wie das Durchsuchen, das Bearbeiten oder die Bindung an Einträge im
- <acronym>LDAP</acronym> Verzeichnis, durchgeführt werden können.
- </para>
- <sect2 id="zend.ldap.introduction.theory-of-operations">
- <title>Theorie der Verwendung</title>
- <para>
- Diese Komponente besteht aus der Hauptklasse <classname>Zend_Ldap</classname> welche
- konzeptionell eine Bindung an einen einzelnen <acronym>LDAP</acronym> Server
- repräsentiert und die Ausführung von Operationen an diesem <acronym>LDAP</acronym>
- Server erlaubt, wie zum Beispiel OpenLDAP oder ActiveDirectory (AD) Server. Die
- Parameter für das Binden können explizit oder in der Form eines Options Arrays
- angegeben werden. <classname>Zend_Ldap_Node</classname> bietet ein Objektorientiertes
- Interface für einen einzelnen <acronym>LDAP</acronym> Node und kann verwendet werden
- um eine Basis für ein Active-Record artiges Interface für ein <acronym>LDAP</acronym>
- basiertes Domain-Modell zu bieten.
- </para>
- <para>
- Die Komponente bietet verschiedene Helfer Klassen um Operationen auf
- <acronym>LDAP</acronym> Einträgen (<classname>Zend_Ldap_Attribute</classname>)
- durchzuführen, wie das Setzen und Empfangen von Attributen (Datumswerte, Passwörter,
- Boolsche Werte, ...), um <acronym>LDAP</acronym> Filter Strings
- (<classname>Zend_Ldap_Filter</classname>) zu Erstellen und zu Ändern, und um
- <acronym>LDAP</acronym> Distinguished Names (DN) (<classname>Zend_Ldap_Dn</classname>)
- zu manipulieren.
- </para>
- <para>
- Zusätzlich abstrahiert die Komponente das Suchen im <acronym>LDAP</acronym> Schema
- für OpenLDAP und ActiveDirectory Server <classname>Zend_Ldap_Node_Schema</classname>
- und das empfangen von Server Informationen für OpenLDAP-, ActiveDirectory- und Novell
- eDirectory Server (<classname>Zend_Ldap_Node_RootDse</classname>).
- </para>
- <para>
- Die Verwendung der <classname>Zend_Ldap</classname> Klasse hängt vom Typ des
- <acronym>LDAP</acronym> Servers ab und wird am besten mit einigen einfachen Beispielen
- gezeigt.
- </para>
- <para>
- Wenn man OpenLDAP Verwendet sieht ein einfaches Beispiel wie folgt aus
- (es ist zu beachten das die <emphasis>bindRequiresDn</emphasis> Option wichtig ist wenn
- man <emphasis>nicht</emphasis> AD verwendet):
- </para>
- <programlisting language="php"><![CDATA[
- $options = array(
- 'host' => 's0.foo.net',
- 'username' => 'CN=user1,DC=foo,DC=net',
- 'password' => 'pass1',
- 'bindRequiresDn' => true,
- 'accountDomainName' => 'foo.net',
- 'baseDn' => 'OU=Sales,DC=foo,DC=net',
- );
- $ldap = new Zend_Ldap($options);
- $acctname = $ldap->getCanonicalAccountName('abaker',
- Zend_Ldap::ACCTNAME_FORM_DN);
- echo "$acctname\n";
- ]]></programlisting>
- <para>
- Wenn man Microsoft AD verwendet ist ein einfaches Beispiel:
- </para>
- <programlisting language="php"><![CDATA[
- $options = array(
- 'host' => 'dc1.w.net',
- 'useStartTls' => true,
- 'username' => 'user1@w.net',
- 'password' => 'pass1',
- 'accountDomainName' => 'w.net',
- 'accountDomainNameShort' => 'W',
- 'baseDn' => 'CN=Users,DC=w,DC=net',
- );
- $ldap = new Zend_Ldap($options);
- $acctname = $ldap->getCanonicalAccountName('bcarter',
- Zend_Ldap::ACCTNAME_FORM_DN);
- echo "$acctname\n";
- ]]></programlisting>
- <para>
- Es ist zu beachten das die <methodname>getCanonicalAccountName()</methodname> Methode
- verwendet wird um den DN Account zu empfangen da jenes das einige ist was das meiste
- in diesem kleinen Code zeigt der aktuell in dieser Klasse vorhanden ist.
- </para>
- <sect3 id="zend.ldap.introduction.theory-of-operations.automatic-username-canonicalization">
- <title>Automatische Kanonisierung des Benutzernamens beim Binden</title>
- <para>
- Wenn <code>bind()</code> mit einem nicht-DN Benutzernamen aufgerufen wird
- aber <code>bindRequiresDN</code> <constant>TRUE</constant> ist und kein
- Benutzername in DN-Form als Option angegeben wurde, dann wird die Server-Bindung
- fehlschlagen. Wenn allerdings ein Benutzername in DN-Form im Optionen-Array
- übergeben wurde, wird <classname>Zend_Ldap</classname> sich zuerst mit diesem
- Benutzernamen an den Server binden, den Account DN für den Benutzernamen empfangen
- der bei <code>bind()</code> angegeben wurde und dann mit diesem zum DN verbinden.
- </para>
- <para>
- Dieses Verhalten ist kritisch für <link
- linkend="zend.auth.adapter.ldap"><classname>Zend_Auth_Adapter_Ldap</classname></link>,
- welches den vom Benutzer angegebenen Benutzernamen direkt an
- <methodname>bind()</methodname> übergibt.
- </para>
- <para>
- Das folgende Beispiel zeigt wie der nicht-DN Benutzername
- '<emphasis>abaker</emphasis>' mit <methodname>bind()</methodname> verwendet werden
- kann:
- </para>
- <programlisting language="php"><![CDATA[
- $options = array(
- 'host' => 's0.foo.net',
- 'username' => 'CN=user1,DC=foo,DC=net',
- 'password' => 'pass1',
- 'bindRequiresDn' => true,
- 'accountDomainName' => 'foo.net',
- 'baseDn' => 'OU=Sales,DC=foo,DC=net',
- );
- $ldap = new Zend_Ldap($options);
- $ldap->bind('abaker', 'moonbike55');
- $acctname = $ldap->getCanonicalAccountName('abaker',
- Zend_Ldap::ACCTNAME_FORM_DN);
- echo "$acctname\n";
- ]]></programlisting>
- <para>
- Der Aufruf von <methodname>bind()</methodname> in diesem Beispiel sieht das der
- Benutzer '<emphasis>abaker</emphasis>' nicht in DN Form ist, findet das
- <emphasis>bindRequiresDn</emphasis> <constant>TRUE</constant> ist, verwendet
- '<command>CN=user1,DC=foo,DC=net</command>' und '<emphasis>pass1</emphasis>' um zu
- Binden, empfängt den DN für '<emphasis>abaker</emphasis>', entbindet und Bindet
- dann nochmals mit dem neu erkannten
- '<command>CN=Alice Baker,OU=Sales,DC=foo,DC=net</command>'.
- </para>
- </sect3>
- <sect3 id="zend.ldap.introduction.theory-of-operations.account-name-canonicalization">
- <title>Kanonisierung des Account Namens</title>
- <para>
- Die Optionen <emphasis>accountDomainName</emphasis> und
- <emphasis>accountDomainNameShort</emphasis> werden für zwei Zwecke verwendet:
- (1) bieten Sie multi-Domain Authentifizierung und Failover Möglichkeiten, und
- (2) werden Sie auch verwendet um Benutzernamen zu kanonisieren. Speziell Namen
- werden in die Form kanonisiert die in der <emphasis>accountCanonicalForm</emphasis>
- Option spezifiziert ist. Diese Option kann einen der folgenden Werte enthalten:
- </para>
- <table id="zend.ldap.using.theory-of-operation.account-name-canonicalization.table">
- <title>Optionen für accountCanonicalForm</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Name</entry>
- <entry>Wert</entry>
- <entry>Beispiel</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry><constant>ACCTNAME_FORM_DN</constant></entry>
- <entry>1</entry>
- <entry>CN=Alice Baker,CN=Users,DC=example,DC=com</entry>
- </row>
- <row>
- <entry><constant>ACCTNAME_FORM_USERNAME</constant></entry>
- <entry>2</entry>
- <entry>abaker</entry>
- </row>
- <row>
- <entry><constant>ACCTNAME_FORM_BACKSLASH</constant></entry>
- <entry>3</entry>
- <entry>EXAMPLE\abaker</entry>
- </row>
- <row>
- <entry><constant>ACCTNAME_FORM_PRINCIPAL</constant></entry>
- <entry>4</entry>
- <entry><filename>abaker@example.com</filename></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Die Standardmäßige Kanonisierung hängt davon ab welche Optionen für Account Domain
- Namen angegeben wurden. Wenn <emphasis>accountDomainNameShort</emphasis> angegeben
- wurde, ist der Standardwert von <emphasis>accountCanonicalForm</emphasis>
- <constant>ACCTNAME_FORM_BACKSLASH</constant>. Andernfall, wenn
- <emphasis>accountDomainName</emphasis> angegeben wurde, ist der Standardwert
- <constant>ACCTNAME_FORM_PRINCIPAL</constant>.
- </para>
- <para>
- Die Kanonisierung des Account Namens stellt sicher das der String der zur
- Identifikation des Accounts verwendet wird konsistent ist, unabhängig davon was an
- <methodname>bind()</methodname> übergeben wurde. Wenn der Benutzer, zum Beispiel,
- den Account Namen <filename>abaker@example.com</filename> oder nur
- <emphasis>abaker</emphasis> angibt, und <emphasis>accountCanonicalForm</emphasis>
- auf 3 gesetzt ist, wird der resultierende kanonisierte Name
- <emphasis>EXAMPLE\abaker</emphasis> sein.
- </para>
- </sect3>
- <sect3 id="zend.ldap.introduction.theory-of-operations.multi-domain-failover">
- <title>Multi-Domain Authentifizierung und Failover</title>
- <para>
- Die Komponente <classname>Zend_Ldap</classname> macht von sich aus keinen Versuch
- sich bei mehreren Servern zu authentifizieren. Trotzdem wurde
- <classname>Zend_Ldap</classname> speziell dafür designt um einfach durch ein Array
- von Array von angebotenen Optionen zu iterieren und sich mit jedem Server zu
- binden. Wie oben beschrieben wird <methodname>bind()</methodname> automatisch jeden
- Namen kanonisieren, damit es egal ist ob der Benutzer
- <filename>abaker@foo.net</filename> oder <emphasis>W\bcarter</emphasis> oder
- <emphasis>cdavis</emphasis> übergibt - die <methodname>bind()</methodname> Methode
- ist nur dann erfolgreich wenn die Benutzerdaten erfolgreich beim Binden verwendet
- wurden.
- </para>
- <para>
- Nehmen wir das folgende Beispiel an das die benötigten Techniken zeigt um eine
- Multi-Domain Authentifizierung und Failover zu implementieren:
- </para>
- <programlisting language="php"><![CDATA[
- $acctname = 'W\\user2';
- $password = 'pass2';
- $multiOptions = array(
- 'server1' => array(
- 'host' => 's0.foo.net',
- 'username' => 'CN=user1,DC=foo,DC=net',
- 'password' => 'pass1',
- 'bindRequiresDn' => true,
- 'accountDomainName' => 'foo.net',
- 'accountDomainNameShort' => 'FOO',
- 'accountCanonicalForm' => 4, // ACCT_FORM_PRINCIPAL
- 'baseDn' => 'OU=Sales,DC=foo,DC=net',
- ),
- 'server2' => array(
- 'host' => 'dc1.w.net',
- 'useSsl' => true,
- 'username' => 'user1@w.net',
- 'password' => 'pass1',
- 'accountDomainName' => 'w.net',
- 'accountDomainNameShort' => 'W',
- 'accountCanonicalForm' => 4, // ACCT_FORM_PRINCIPAL
- 'baseDn' => 'CN=Users,DC=w,DC=net',
- ),
- );
- $ldap = new Zend_Ldap();
- foreach ($multiOptions as $name => $options) {
- echo "Versuch zu binden un die Serveroptionen für '$name' zu verwenden\n";
- $ldap->setOptions($options);
- try {
- $ldap->bind($acctname, $password);
- $acctname = $ldap->getCanonicalAccountName($acctname);
- echo "Erfolgreich: $acctname authentifiziert\n";
- return;
- } catch (Zend_Ldap_Exception $zle) {
- echo ' ' . $zle->getMessage() . "\n";
- if ($zle->getCode() === Zend_Ldap_Exception::LDAP_X_DOMAIN_MISMATCH) {
- continue;
- }
- }
- }
- ]]></programlisting>
- <para>
- Wenn das Binden aus irgendeinem Grund fehlschlägt, werden die nächsten
- Serveroptionen probiert.
- </para>
- <para>
- Der Aufruf von <methodname>getCanonicalAccountName()</methodname> erhält den
- kanonisierten Accountnamen welcher der Anwendung voraussichtlich verwendet um
- zugehörige Daten bevorzugt zu assoziieren.
- <emphasis>accountCanonicalForm = 4</emphasis> in allen Serveroptionen stellt
- sicher das die kanonisierte Form angenommen wird, egal welcher Server letztendlich
- verwendet wird.
- </para>
- <para>
- Die spezielle Exception <constant>LDAP_X_DOMAIN_MISMATCH</constant> tritt auf wenn
- ein Account Name bei einer Domain Komponente übergeben wurde (z.B.
- <filename>abaker@foo.net</filename> oder <emphasis>FOO\abaker</emphasis> und nicht
- nur <emphasis>abaker</emphasis>) aber die Domain Komponente keiner der Domains in
- den aktuell ausgewählten Server Optionen entspricht. Diese Exception zeigt das der
- Server keine Autorität für den Account ist. In diesem Fall wird das Binden nicht
- durchgeführt, und damit unnötige Kommunikation mit dem Server verhindert. Es ist zu
- beachten das die <emphasis>continue</emphasis> Anweisung in diesem Beispiel keinen
- Effekt hat, aber in der Praxis für Fehlerbehandlung und Debugging Zwecke verwendet
- wird, da man warscheinlich auf <constant>LDAP_X_DOMAIN_MISMATCH</constant> sowie
- <constant>LDAP_NO_SUCH_OBJECT</constant> und
- <constant>LDAP_INVALID_CREDENTIALS</constant> prüfen will.
- </para>
- <para>
- Der obige Code ist dem Code der in <link
- linkend="zend.auth.adapter.ldap"><classname>Zend_Auth_Adapter_Ldap</classname></link>
- verwendet wurde sehr ähnlich. Fakt ist, das wir einfach empfehlen den
- Authentifizierungs Adapter für Multi-Domain und Failover basierte
- <acronym>LDAP</acronym> Authentifizierung zu verwenden (oder den Code zu kopieren).
- </para>
- </sect3>
- </sect2>
- </sect1>
|