Ich habe hier die LDAP Verbindung in eine eigene Klasse (LdapConnectionHelper) ausgelagert um diese wiederverwenden zu können. Zudem habe ich noch die Verbindung in LdapAuthService dementsprechend angepasst. Co-authored-by: blaerf <blaerf@gmx.de> Reviewed-on: https://git.eckertplayground.de/taarly/PHP_AdminTool_Projekt/pulls/3
89 lines
3.7 KiB
PHP
89 lines
3.7 KiB
PHP
<?php
|
|
|
|
// Strenge Typprüfung für Parameter- und Rückgabetypen aktivieren.
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\Ldap;
|
|
|
|
use RuntimeException;
|
|
|
|
/**
|
|
* Service zur Authentifizierung von Benutzern gegen ein Active Directory per LDAP/LDAPS.
|
|
* Bekommt Benutzername und Passwort und liefert:
|
|
* - true -> Anmeldedaten sind gültig
|
|
* - false -> Anmeldedaten sind fachlich ungültig (z. B. falsches Passwort)
|
|
* Technische Fehler (z. B. falsche Konfiguration, keine Verbindung) werden als Exception geworfen.
|
|
*/
|
|
class LdapAuthService
|
|
{
|
|
/** @var array<string, mixed> LDAP-spezifische Konfiguration (Server, Port, Domain-Suffix, Timeout, etc.) */
|
|
private array $config;
|
|
|
|
private LdapConnectionHelper $connectionHelper;
|
|
|
|
/**
|
|
* Erwartet den Teilbereich "ldap" aus der allgemeinen Konfiguration (config.php).
|
|
*
|
|
* @param array<string, mixed> $ldapConfig Konfiguration für die LDAP-Verbindung
|
|
*/
|
|
public function __construct(array $ldapConfig)
|
|
{
|
|
// LDAP-Konfiguration in der Instanz speichern.
|
|
$this->config = $ldapConfig;
|
|
$this->connectionHelper = new LdapConnectionHelper($ldapConfig);
|
|
}
|
|
|
|
/**
|
|
* Führt die eigentliche LDAP/AD-Authentifizierung durch.
|
|
*
|
|
* @param string $username Benutzername (ohne Domain-Suffix, z. B. "administrator")
|
|
* @param string $password Passwort im Klartext (wird direkt an ldap_bind übergeben)
|
|
*
|
|
* @return bool true bei erfolgreicher Anmeldung, false bei fachlich ungültigen Anmeldedaten
|
|
*
|
|
* @throws RuntimeException bei technischen Problemen (z. B. fehlende Konfiguration, Verbindungsfehler)
|
|
*/
|
|
public function authenticate(string $username, string $password): bool
|
|
{
|
|
// Wenn Benutzername oder Passwort leer sind, gar nicht erst versuchen zu binden.
|
|
// Das ist ein fachlich ungültiger Login und wird mit false behandelt.
|
|
if ($username === '' || $password === '') {
|
|
return false;
|
|
}
|
|
|
|
// Benötigte Werte aus der LDAP-Konfiguration auslesen.
|
|
// Falls einzelne Werte fehlen, werden sinnvolle Standardwerte gesetzt.
|
|
$domainSuffix = (string)($this->config['domain_suffix'] ?? '');
|
|
|
|
// Ohne Server-Adresse oder Domain-Suffix ist eine sinnvolle Anmeldung nicht möglich.
|
|
// Das ist ein Konfigurationsfehler und wird als technischer Fehler behandelt.
|
|
if ($domainSuffix === '') {
|
|
throw new RuntimeException('LDAP-Konfiguration ist unvollständig (domain_suffix fehlt).');
|
|
}
|
|
|
|
// Verbindung zum LDAP/AD-Server herstellen.
|
|
// Rückgabewert ist eine Ressource (Verbindungshandle) oder false bei Fehlern.
|
|
$connection = $this->connectionHelper->createConnection();
|
|
|
|
// UPN (User Principal Name) aus Benutzername und Domain-Suffix bilden.
|
|
// Beispiel: "administrator" + "@ITFA-PROJ-DOM.local" -> "administrator@ITFA-PROJ-DOM.local"
|
|
$bindRdn = $username . $domainSuffix;
|
|
|
|
// Eigentliche Authentifizierung:
|
|
// ldap_bind versucht, sich mit den angegebenen Anmeldedaten am AD/LDAP anzumelden.
|
|
// Rückgabewerte:
|
|
// - true -> Anmeldedaten sind gültig
|
|
// - false -> Anmeldedaten sind ungültig (z. B. falsches Passwort)
|
|
//
|
|
// Das @-Zeichen unterdrückt PHP-Warnings, damit Fehlermeldungen nicht unformatiert im HTML landen.
|
|
$bindResult = @ldap_bind($connection, $bindRdn, $password);
|
|
|
|
// Verbindung zum LDAP-Server wieder schließen.
|
|
ldap_unbind($connection);
|
|
|
|
// Bei erfolgreichem Bind (true) -> Authentifizierung erfolgreich.
|
|
// Bei false -> fachlich fehlgeschlagene Anmeldung (z. B. falsche Credentials).
|
|
return $bindResult === true;
|
|
}
|
|
}
|