Zwei-Faktor-Anmeldung per TOTP
app/totp.php implementiert RFC 6238 selbst statt per Bibliothek: der Algorithmus ist ein HMAC plus eine Truncation, und ein zweiter Faktor ist die letzte Stelle fuer ungepruefte Abhaengigkeiten. Der QR-Code entsteht aus dem ohnehin vorhandenen TCPDF, damit kein externer Dienst das Geheimnis sieht. Beim Login wird die Anmeldung bei aktivem zweitem Faktor nicht abgeschlossen; der Zwischenzustand gewaehrt keinerlei Zugriff und ist byte-identisch zu einem unangemeldeten Aufruf. users.totp_last_step verhindert die Wiederverwendung eines abgefangenen Codes innerhalb seines Gueltigkeitsfensters. Abschalten verlangt Passwort und Code. APP_REQUIRE_2FA_FOR_ADMINS macht den Faktor fuer Platform-Admins verbindlich, per Weiterleitung auf die Einrichtung statt als harte Sperre - sonst koennte der Schalter den einzigen Admin aussperren. Standard aus. check-konto-und-mandantenwechsel erwartete beim Login noch das entfernte Kundenkuerzel-Feld und damit einen direkten Sprung aufs Dashboard; der Check bildet jetzt den tatsaechlichen Weg ueber die Mandantenauswahl ab. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
require_once __DIR__ . '/functions.php';
|
||||
require_once __DIR__ . '/app/rate-limit.php';
|
||||
require_once __DIR__ . '/app/totp.php';
|
||||
|
||||
$pdo = app_db_pdo();
|
||||
$errors = [];
|
||||
@@ -25,6 +26,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
(string)($_POST['password'] ?? '')
|
||||
);
|
||||
|
||||
// Stimmt das Passwort und ist ein zweiter Faktor scharf, wird die
|
||||
// Anmeldung hier nicht abgeschlossen: es entsteht nur ein
|
||||
// Zwischenzustand ohne jeden Zugriff. Das gilt fuer beide Faelle -
|
||||
// auch wer noch einen Mandanten auswaehlen muesste, kommt erst nach
|
||||
// dem Code dorthin.
|
||||
if ($result['ok']) {
|
||||
$totpUserId = (int)($result['user_id'] ?? $result['identity']['user_id'] ?? 0);
|
||||
if ($totpUserId > 0 && app_totp_is_active($pdo, $totpUserId)) {
|
||||
app_totp_start_challenge($totpUserId);
|
||||
header('Location: zwei-faktor.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ($result['ok'] && !empty($result['needs_tenant_selection'])) {
|
||||
saas_start_pending_tenant_selection((int)$result['user_id']);
|
||||
header('Location: mandant-auswahl.php');
|
||||
|
||||
Reference in New Issue
Block a user