PHP_AdminTool_Projekt/app/Services/Ldap/LdapAuthService.php
blaerf 717aca3617 ldap/connection-helper (#3)
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
2025-11-19 21:09:56 +00:00

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;
}
}