6.7 KiB
HausPilot: Authentifizierungs- und Benutzerintegration
Ergebnis der Boilerplate-Analyse
HausPilot verwendet unveraendert die vorhandene Backend-for-Frontend-
Authentifizierung. Das Boilerplate spricht keinen bestimmten Hersteller fest,
sondern einen ueber OIDC_ISSUER konfigurierten OpenID-Connect-Provider. Der
Login ist ein OIDC Authorization Code Flow mit PKCE, state und nonce.
Der Browser startet den Login ueber GET /api/auth/login. Der Callback liegt
fest unter <APP_BASE_URL>/api/auth/callback. Der Backend-Callback validiert
Issuer, Audience, Signaturalgorithmus, Nonce und Subject, laedt gegebenenfalls
UserInfo und legt den lokalen Benutzer an oder aktualisiert ihn. Die stabile
Identitaet beim Provider ist (issuer, subject); fachliche Beziehungen verwenden
ausschliesslich die interne UUID users.id.
OIDC Access-, Refresh- und ID-Tokens werden verschluesselt in der MySQL-Tabelle
sessions gespeichert. Der Browser erhaelt nur eine signierte, HttpOnly
Session-ID und ein lesbares CSRF-Cookie. Schreibende Requests senden dieses
Cookie ueber den vorhandenen csrfInterceptor als X-CSRF-Token. Idle- und
Absolute-Timeout werden beim serverseitigen Session-Resolve geprueft. Es gibt
keinen zweiten Token-Refresh im Browser.
Der globale PermissionsGuard loest die Session auf, prueft den globalen
Benutzerstatus und setzt AuthenticatedRequest.user mit interner UUID,
Session-ID und effektiven Permissions. Controller verwenden weiterhin
@RequirePermissions(...). Deaktivierte Benutzer werden beim Login und bei
jeder Session-Aufloesung abgewiesen; ihre historischen fachlichen Beziehungen
werden nicht geloescht.
Angular ermittelt den aktuellen Benutzer ueber AuthService.ensureLoaded() und
GET /api/me. Der Auth-State liegt ausschliesslich in dessen Signals. Der
vorhandene permissionGuard steuert nur Navigation und Darstellung; das Backend
bleibt verbindlich. Logout erfolgt ausschliesslich ueber /api/auth/logout,
widerruft die lokale Session, loescht Session- und CSRF-Cookie und verwendet
danach den OIDC end_session_endpoint beziehungsweise OIDC_LOGOUT_URL.
Registrierung und Benutzerprofil
Das Boilerplate besitzt keinen lokalen Registrierungs- oder Passwortdialog und keine lokale Passwort-Entity. Konten werden durch den vorhandenen Identity Provider registriert oder bereitgestellt und beim ersten erfolgreichen OIDC- Login lokal synchronisiert. HausPilot fuehrt daher keine zweite Registrierung ein. Nach dem ersten Login werden offene Einladungen nur angezeigt, niemals automatisch angenommen.
Die lokale UserEntity speichert UUID, Issuer, Subject, Anzeigename, E-Mail,
Aktivstatus, globale Rollen und Einstellungen. Name und E-Mail werden bei jedem
Login aus dem OIDC-Profil aktualisiert. Aktive Mitgliedschaften bleiben auch bei
einer E-Mail-Aenderung ueber users.id stabil. Offene Einladungen bleiben an die
normalisierte urspruengliche Zieladresse gebunden.
Die Integration uebernimmt ausserdem den standardisierten OIDC-Claim
email_verified. Eine Einladung kann nur angenommen werden, wenn der Provider
die aktuelle Zieladresse als verifiziert bestaetigt. Fehlt diese Bestaetigung,
wird die Annahme sicher abgewiesen.
Globale und projektbezogene Autorisierung
Globale Rollen (admin, user und verwaltete globale Rollen) bleiben von den
HausPilot-Projektrollen getrennt. Eine globale Basis-Permission erlaubt nur die
Verwendung der Projekt-API. Sie erzeugt weder eine Mitgliedschaft noch einen
Zugriff auf ein privates Projekt. Insbesondere erhaelt ein globaler Administrator
keinen impliziten Projektzugriff.
Projektrollen sind owner, administrator, editor und reader. Jede
Projektabfrage prueft serverseitig eine aktive Mitgliedschaft und die fuer die
Aktion erforderliche Rolle. Unterentitaeten werden immer zusammen mit der
Projekt-ID geladen beziehungsweise geprueft. Eigentuermer-, Autor- und
Einladender-IDs sind keine DTO-Felder, sondern stammen aus dem vorhandenen
serverseitigen Current-User-Kontext.
Projektanlage, Eigentuemermitgliedschaft und Erstellungsaktivitaet werden in einer Datenbanktransaktion gespeichert. Projektrollen entstehen nur durch diese Projektanlage, explizite Einladungsannahme oder eine berechtigte Aenderung im Projekt; OIDC-Gruppen und globale Rollen werden nicht abgebildet.
Einladungen und sicherer Rueckkehrpfad
Einladungen speichern die normalisierte E-Mail-Adresse und optional die bekannte
interne Benutzer-ID. Der zufaellige Einladungstoken wird nur im Link ausgegeben;
in MySQL liegt ausschliesslich sein SHA-256-Hash. Annahme und Ablehnung verlangen
eine gueltige bestehende Session. Das Backend prueft Status, Ablauf,
Widerruf, Zieladresse, email_verified, aktiven Benutzer und eine noch nicht
bestehende aktive Mitgliedschaft. Fehlermeldungen geben nur eine maskierte
Adresse aus.
Ist ein Besucher nicht angemeldet, verweist Angular auf den bestehenden
/api/auth/login-Flow. Der gewuenschte Rueckweg wird serverseitig im kurzlebigen
OIDC-Login-State gehalten. Erlaubt sind nur interne Pfade; Schemes,
Protokoll-relative URLs und Backslashes werden verworfen. Nach dem Callback baut
das Backend das Ziel relativ zu FRONTEND_BASE_URL auf. Tokens oder OIDC-Daten
werden nie in Rueckkehrparametern gespeichert.
Benachrichtigungen, Mail und Cleanup
Das vorhandene NotificationsService erzeugt fuer bereits bekannte aktive
Benutzer eine persoenliche In-App-Benachrichtigung. Normale Endpunkte bleiben auf
den Session-Benutzer beschraenkt. Das Boilerplate hat keinen Mail-Service, keine
Templates, Queue oder Retry-Jobs. HausPilot fuehrt keine parallele
Mail-Infrastruktur ein; der Versandstatus einer Einladung wird daher explizit
als not_configured gespeichert. Der Einladungsdatensatz bleibt konsistent und
kann spaeter an eine architektonisch beschlossene Mail-Komponente angebunden
werden.
Projektseiten halten Daten nur komponentenlokal. Bei 401 setzt der vorhandene globale Auth-State den Benutzer zurueck; dadurch werden geschuetzte Seiten entfernt und das bestehende Notification-Polling samt personenbezogenem Cache gestoppt. Ein regulaerer Logout verlaesst die SPA und startet sie ohne alten In-Memory-State neu. HausPilot fuehrt keine Live-Verbindungen ein.
Relevante Konfiguration
- OIDC:
OIDC_ISSUER,OIDC_CLIENT_ID,OIDC_CLIENT_SECRET,OIDC_SCOPES,OIDC_ALLOWED_ALGORITHMS, optionalOIDC_LOGOUT_URL - Redirects:
APP_BASE_URL,FRONTEND_BASE_URL - Session:
SESSION_COOKIE_NAME, Idle-/Absolute-Timeout,SESSION_SECRET,SESSION_ENCRYPTION_KEY - Browser-Schutz:
CORS_ORIGINS,CSRF_HEADER_NAME, Secure/SameSite-Cookies, Helmet, Rate Limits und Logging-Redaction
Es wurde keine parallele Authentifizierungs-, Benutzer-, Passwort-, Token-, Registrierungs-, Mail-, Queue- oder Live-Connection-Infrastruktur eingefuehrt.