Authentifizierung in PHP mit LDAP über Active Directory

104

Ich suche nach einer Möglichkeit, Benutzer über LDAP mit PHP zu authentifizieren (wobei Active Directory der Anbieter ist). Idealerweise sollte es unter IIS 7 ausgeführt werden können ( adLDAP unter Apache). Hat jemand etwas Ähnliches mit Erfolg gemacht?

  • Bearbeiten: Ich würde eine Bibliothek / Klasse mit Code bevorzugen, der bereit ist ... Es wäre dumm, das Rad zu erfinden, wenn jemand dies bereits getan hat.
DV.
quelle
Ich denke, Drupal hat ein Modul für thatr
redben

Antworten:

167

Das Importieren einer ganzen Bibliothek scheint ineffizient zu sein, wenn Sie im Wesentlichen nur zwei Codezeilen benötigen ...

$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) {
  // log them in!
} else {
  // error message
}
ceejayoz
quelle
43
Einige Installationen von AD werden erfolgreich gebunden, wenn das angegebene Kennwort leer ist. Achte darauf! Möglicherweise müssen Sie ein nicht leeres Kennwort sicherstellen, bevor Sie versuchen, sich zu authentifizieren.
Diolemo
@diolemo Gibt es eine Möglichkeit, dies zu verhindern, ohne zu überprüfen, ob das Passwort leer ist?
Naftali aka Neal
@Neal Sie können es möglicherweise verwenden ldap_set_option, um es anders zu verhalten. Vielleicht die Protokollversion einstellen? Sie müssen experimentieren. Ich würde Ihnen persönlich empfehlen, ohnehin nach einem leeren Passwort zu suchen, um sicher zu gehen.
Diolemo
@diolemo Ich habe eine neue Frage dazu gestellt.
Naftali aka Neal
An den anonymen Redakteur: Nein, meines Wissens ist hier keine Bereinigung der Eingaben erforderlich, wie ldap_binddies der Fall wäre, und Sonderzeichen sind kein Problem.
Ceejayoz
14

Sie würden denken, dass die einfache Authentifizierung eines Benutzers in Active Directory ein ziemlich einfacher Prozess mit LDAP in PHP wäre, ohne dass eine Bibliothek erforderlich wäre. Aber es gibt viele Dinge, die es ziemlich schnell komplizieren können:

  • Sie müssen die Eingabe validieren. Ein leerer Benutzername / Passwort würde sonst übergeben.
  • Sie sollten sicherstellen, dass der Benutzername / das Passwort beim Binden ordnungsgemäß codiert ist.
  • Sie sollten die Verbindung mit TLS verschlüsseln.
  • Verwendung separater LDAP-Server für Redundanz, falls einer ausfällt.
  • Eine informative Fehlermeldung erhalten, wenn die Authentifizierung fehlschlägt.

In den meisten Fällen ist es tatsächlich einfacher, eine LDAP-Bibliothek zu verwenden, die die oben genannten Funktionen unterstützt. Am Ende habe ich meine eigene Bibliothek gerollt , die alle oben genannten Punkte behandelt: LdapTools (Nun, nicht nur zur Authentifizierung, es kann noch viel mehr). Es kann wie folgt verwendet werden:

use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;

$domain = (new DomainConfiguration('example.com'))
    ->setUsername('username') # A separate AD service account used by your app
    ->setPassword('password')
    ->setServers(['dc1', 'dc2', 'dc3'])
    ->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);

if (!$ldap->authenticate($username, $password, $message)) {
    echo "Error: $message";
} else {
    // Do something...
}

Der obige Authentifizierungsaufruf wird:

  • Stellen Sie sicher, dass weder der Benutzername noch das Passwort leer sind.
  • Stellen Sie sicher, dass der Benutzername / das Kennwort ordnungsgemäß codiert ist (standardmäßig UTF-8).
  • Versuchen Sie es mit einem alternativen LDAP-Server, falls einer ausfällt.
  • Verschlüsseln Sie die Authentifizierungsanforderung mit TLS.
  • Geben Sie zusätzliche Informationen an, wenn dies fehlgeschlagen ist (z. B. gesperrtes / deaktiviertes Konto usw.).

Es gibt auch andere Bibliotheken, die dies tun (z. B. Adldap2). Ich fühlte mich jedoch gezwungen genug, einige zusätzliche Informationen bereitzustellen, da die am besten bewertete Antwort tatsächlich ein Sicherheitsrisiko darstellt, auf das ich mich verlassen kann, wenn keine Eingabevalidierung durchgeführt wird und kein TLS verwendet wird.

ChadSikorra
quelle
1
Für LDAP-Verbindungen wurde TLS zugunsten von StartTLS abgelehnt : openldap.org/faq/data/cache/605.html .
Zenlord
2
@zenlord Die Verwendung des ldaps://Formats für die Verbindung ist veraltet. In meinem Beispiel wird beim Angeben setUseTls(true)das ldap://Format verwendet und anschließend ein StartTLS mit ausgegeben ldap_start_tls($connection). TLS selbst ist also nicht veraltet, sondern stellt nur eine Verbindung über ldaps://(die tatsächlich über einen völlig anderen Port eine Verbindung zu LDAP herstellt).
ChadSikorra
12

Dazu übergebe ich einfach die Benutzeranmeldeinformationen an ldap_bind ().

http://php.net/manual/en/function.ldap-bind.php

Wenn das Konto an LDAP gebunden werden kann, ist es gültig. Wenn es nicht kann, ist es nicht. Wenn Sie nur eine Authentifizierung (keine Kontoverwaltung) durchführen, sehe ich keine Notwendigkeit für eine Bibliothek.

Scott Reynen
quelle
9

Ich mag die Zend_Ldap- Klasse. Sie können nur diese Klasse in Ihrem Projekt ohne das Zend Framework verwenden.

CMS
quelle
1
Ich habe mir die Mühe gemacht, das oben Genannte zu implementieren, um herauszufinden, dass es für die Verwaltung der Nichtauthentifizierung war. Ich beabsichtige, zu zend.auth.adapter.ldap
vdidxho