Nutzung von PHP und dessen LDAP-Authentifizierung für Windows und UNIX

(http://www.zdnet.de/magazin/20000801/nutzung-von-php-und-dessen-ldap-authentifizierung-fuer-windows-und-unix.htm)

von Shylon Ray Hunter, Builder.com, 24. Januar 2003

Bei der Suche nach einem Standardverfahren zur Authentifizierung von Intranet-Diensten besteht eine der entscheidenden Herausforderungen darin, dass zwei große Plattformen benutzt werden: UNIX und Windows.

Die beste Lösung für das Problem der aus UNIX und Windows bestehenden Architektur ist die Nutzung der LDAP-Funktionen von PHP. Für den LDAP-Server sollte ich auf das vorhandene System zurückgreifen, bei dem es sich vorwiegend um ein riesiges Microsoft Exchange Server-System handelt. Die Aussicht auf eine Nutzung von Exchange begeisterte mich zwar nicht gerade, doch hatte sich das System als zuverlässig erwiesen und seine LDAP-Funktionen sind äußerst einfach zu handhaben und einzurichten. Dennoch ist zu beachten, dass dies keineswegs das sicherste Verfahren zur Authentifizierung darstellt. Bei besonders hohen Sicherheitsanforderungen empfiehlt sich die Verwendung von LDAP und SSL.

Erste Schritte

Zunächst werde ich die wichtigsten LDAP-Funktionen von PHP vorstellen und deren Zweck kurz erläutern. Dann werde ich zeigen, wie man eine Verbindung zu einem LDAP-Server erstellt und diesen zur Benutzerauthentifizierung einsetzt. Anhand von Code-Beispielen werde ich schließlich die Möglichkeiten von PHP für den Verbindungsaufbau und die Bindung an einen LDAP-Server demonstrieren.

Im Folgenden sind die Funktionen aufgelistet, die ich in meinen Beispielen verwenden werde. Diese stehen auch online[1] zur Verfügung.

Nun werde ich anhand eines Beispiels (Listing A) die erste Funktion vorstellen und anschließend ihre Bedeutung und ihren Zweck erläutern.

In Listing A[2] wird eine Verbindung (Ressource) zum LDAP-Server gezeigt. Für die Funktion ldap_connect können zwei Parameter verwendet werden: host und port. Der erste Parameter, host, ist dabei der Name des LDAP-Hosts, wobei der zweite Parameter den Port bezeichnet, auf dem LDAP ausgeführt wird. Standardmäßig wird LDAP auf Port 389 ausgeführt. Sollte eine sichere Verbindung zu dem LDAP-Server erforderlich (oder gewünscht) sein, kann der Host wie folgt in eine festgelegte URL des LDAP-Servers geändert werden:

In diesem Fall wird der Port-Parameter nicht verwendet, da statt eines Servernamens eine URL angegeben wird. Dabei ist zu beachten, dass der Servername exakt wie im SSL-Zertifikat einzugeben ist.

Nun besteht eine Verbindung zum LDAP-Server, so dass ich im Folgenden mit der Bindung an den Server fortfahren kann. Ich verwende dabei einen existierenden Benutzernamen mit Passwort für die Authentifizierung. Durch die Bindung an den Server wird überprüft, ob die Kombination aus Benutzername und Passwort korrekt ist, wobei der Benutzer im Falle einer erfolgreichen Bindung authentifiziert wird. Wenn die Bindung fehlschlägt, wurde der Benutzer nicht authentifiziert.

Listing B[3] zeigt wie eine Bindung an den Server mit einem Benutzernamen und einem Passwort erfolgt. Ich habe den exakten Domänennamen (DN) eingegeben und das Passwort des Benutzers verwendet um eine ordnungsgemäße Verbindung zum LDAP herzustellen. Durch die Verwendung von DN und Passwort kann das LDAP eine Authentifizierung und eine Bindung für die Verbindung durchführen, so dass eine erfolgreiches Bindung entsteht. Die Ausgabe der Funktion ldap_bind erfolgt als boolescher Wert. Daher kann ich sofort erkennen, ob ein Benutzer korrekte Angaben gemacht hat, mit denen ein erfolgreiches Login möglich ist. Nach Abschluss dieses Vorgangs wissen Sie also, ob der Benutzer authentifiziert ist.

Um herauszufinden, welche Fehler eventuell aufgetreten sind, kann man die Funktion ldap_error aufrufen. Sie liefert einen String, der den jeweils letzten am LDAP-Server aufgetretenen Fehler enthält.

In Listing C[4] habe ich die Funktion ldap_error zu dem Script hinzugefügt um im Falle einer fehlgeschlagenen Authentifizierung des Benutzers durch Bindung an den LDAP-Server eine Fehlermeldung anzuzeigen und den Vorgang abzubrechen. Diese Funktion gibt einen String zurück, der die Fehlermeldung enthält, die durch den letzten an den LDAP-Server gesendeten Befehl erzeugt wurde. Wenn eine Bindung mit dem verwendeten Benutzernamen und Passwort nicht möglich war, wird in der Fehlermeldung auf einen ungültigen Benutzernamen bzw. auf ein ungültiges Passwort hingewiesen.

Für das letzte Beispiel in Listing D[5] benutze ich die verbleibenden drei Funktionen ldap_search, ldap_get_entries und ldap_close zusammen.

Nach dem Aufruf der Funktion ldap_bind in Listing D fordere ich Daten vom Server an, indem ich den Server mit der Funktion ldap_search durchsuche. Die Funktion ldap_search akzeptiert zwar verschiedene Parameter, dennoch habe ich in diesem Beispiel nur die ersten drei verwendet. Ich gab also Verbindung, Suchbasis und Filter in die Suchfunktion ein, die den Server ausgehend von den Angaben zu Suchbasis und Filter auf den korrekten Benutzer durchsucht. Kurz gesagt, ich wies die Suchfunktion durch Angabe der UID als Benutzername an, nach dem Benutzer zu suchen. Auf diese Weise filtert LDAP das Ergebnis und gibt nur die LDAP-Daten des Benutzers aus.

Als ich zum ersten Mal mit der LDAP-Erweiterung in PHP arbeitete, irritierte mich die Tatsache, dass die Funktion ldap_search eine Ressource statt eines Arrays oder Strings zurückgab. Nachdem ich mich diesbezüglich informiert hatte, lernte ich rasch, die Funktion ldap_get_entries zum Auffinden der eigentlichen Suchergebnisse einzusetzen. Dabei sollte man daran denken, dass ldap_get_entries die Ergebnisse in einem mehrdimensionalen Array ausgibt. So speicherte ich meine Ergebnisse in einem Array namens $ldap['info'], was etwas verwirrend wirken könnte.

Wenn ich die Ergebnisse erst einmal als mehrdimensionales Array zur Verfügung habe, kann ich auf die gewünschten Daten zugreifen. Ich setze die Abteilung und E-Mail-Adresse des Benutzers in Session-Variablen ein, die ich später in der laufenden Session verwenden kann.

Nachdem ich alle Schritte ausgeführt habe, beende ich die Verbindung durch die Funktion ldap_close. Die Close-Funktion ermöglicht mir die Freigabe der Verbindungsressource. Diese Funktion entspricht im Grunde der Funktion ldap_unbind, die dasselbe bewirkt.

Ein guter Anfang

Auch wenn ich hier nur einige wenige Funktionen der LDAP-Erweiterung gestreift habe, reichen diese bereits für eine Nutzung der LDAP-Authentifizierung aus. PHP und LDAP zusammen bieten ein universell einsetzbares Verfahren zur Authentifizierung von Benutzern in Web-basierten Anwendungen. Mit dem LDAP-Server können Administratoren Rechte zuteilen, die anschließend verifiziert und zur Erteilung oder Verweigerung des Zugriffs auf Daten der Anwendungen verwendet werden können.

URLs in diesem Artikel:
[1] = http://www.php.net/manual/en/ref.ldap.php
[2] = http://www.zdnet.de/i/bld/architect/2003/01/php_ldap_listing_a.html
[3] = http://www.zdnet.de/i/bld/architect/2003/01/php_ldap_listing_b.html
[4] = http://www.zdnet.de/i/bld/architect/2003/01/php_ldap_listing_c.html
[5] = http://www.zdnet.de/i/bld/architect/2003/01/php_ldap_listing_d.html