Jüngst standen wir bei uns am Georg-Büchner-Gymnasium in Seelze vor der Herausforderung, eine eigene PHP-basierte Webanwendung mit PHP-Session-Cookies über den IServ-LDAP authentifizieren zu wollen, um so zu erreichen, dass sich die Nutzerinnen und Nutzer dort mit ihren IServ-Zugangsdaten anmelden können.
Wie sich herausstellte, gab es dabei einige Fallstricke. In diesem Blog-Post werde ich darstellen, was man machen muss, um erfolgreich die Authentifizierung am IServ-LDAP in der PHP-Anwendung durchzuführen.
Als erstes muss man auf dem IServ-Server einen neuen Bind-Benutzer für LDAP anlegen. Dafür muss man in die Datei /etc/iserv/ldapusers folgende Zeile hinzufügen:
gbg-webserver:+userPassword:10.2.31.28
Dabei ist gbg-webserver der Name des Bind-Benutzers und die IP-Adresse ist die unseres Webservers mit der PHP-Anwendung.
Dann muss man mit folgendem Befehl die Konfigurationsänderung sichern:
iconf save /etc/iserv/ldapusers iservchk
Als nächstes muss man das LDAP-Passwort mit
cat /var/lib/iserv/server-openldap/pwd/gbg-webserver.pwd
vom IServ holen. Jetzt kann man auf dem Testsystem prüfen, ob eine LDAP-Abfrage mit dem soeben eingerichteten Bind-Benutzer und dem Passwort geht. Dafür muss man auf dem Server 10.2.31.28 Folgendes ausführen:
ldapsearch -o ldif-wrap=no -H ldaps://gbg-seelze.eu:10636 -D "cn=gbg-webserver,ou=ldap,dc=gbg-seelze,dc=eu" -w PasswortAusVarLibIservEtc -b "cn=user.name,ou=users,dc=gbg-seelze,dc=eu"
Einer der Fallstricke war, dass IServ standardmäßig LDAP v3 nutzt, wohingegen PHP standardmäßig mit LDAP v2 arbeitet. Die Umsetzung der Abfrage sieht dann in PHP implementiert folgendermaßen aus:
$ds=ldap_connect("ldaps://gbg-seelze.eu:10636"); // must be a valid LDAP server! if (ldap_set_option($ds,LDAP_OPT_PROTOCOL_VERSION,3)) { echo "Using LDAP v3"; }else{ echo "Failed to set version to protocol 3"; } if ($ds) { $passwd="PasswortAusVarLibIservEtc"; $r=ldap_bind_ext($ds, "cn=gbg-webserver,ou=ldap,dc=gbg-seelze,dc=eu", $passwd); //cn=... der User aus /etc/iserv/ldapusers if (ldap_parse_result($ds, $r, $errcode, $matcheddn, $errmsg, $referrals, $ctrls)) { if ($errcode != 0) { die("Error: $errmsg ($errcode)"); } } $sq="(memberOf=*)"; echo "Searching for $sq"; $act="erika.mustermann"; // bzw. der zu authentifizierende User $sr=ldap_search($ds, "cn=".$act.",ou=users,dc=gbg-seelze,dc=eu",$sq); if (ldap_parse_result($ds, $sr, $errcode, $matcheddn, $errmsg, $referrals, $ctrls)) { if ($errcode != 0) { die("Error: $errmsg ($errcode)"); } } $info = ldap_get_entries($ds, $sr); //hier sollte nur ein Entry rauskommen (keine Wildcards im User erlauben) for ($i=0; $i<$info["count"]; $i++) { //----------------Passworttesten hier!--------------------------------------- $hashpasswd=explode ("{crypt}",$info[$i]["userpassword"][0])[1]; if (password_verify('testpasswort', $hashpasswd )) { //bzw. das zu testende Passwort echo 'Password is valid!'; } else { echo 'Invalid password.'; } //----------------Gruppenzugehörigkeit hier!------------------------------------ $memberof=[]; for ($j=0; $j<$info[$i]["memberof"]["count"]; $j++) { $memberof[]= explode(",",explode("cn=",$info[$i]["memberof"][$j])[1])[0]; //----------optimistische Auswertung, hier sollte man sich etwas vor Fehlern schützen---- } } print_r($memberof); //$memberof enthält jetzt alle iserv-Gruppenzugehörigkeiten ldap_close($ds);