← Zur Uebersicht

OIDC/Keycloak statt HTTP Basic (Migrationsphase M6)

Fuenfte und letzte Erweiterung aus M6. Loest den in SecurityConfigs eigenem Javadoc (aus M4) bereits benannten "naheliegenden naechsten Ausbauschritt" ein: HTTP Basic + In-Memory- Benutzerspeicher war fuer M4 als angemessener erster Schritt begruendet (reine JSON-REST-API, keine Session/kein eigenes Frontend), aber mit Klartext-aehnlichen Passwoertern im Anwendungscode nicht praxistauglich.

Warum OIDC/Keycloak

Was gebaut wurde

Real geprueft: Verhalten ohne erreichbaren Keycloak

Urspruengliche Annahme beim Schreiben von SecurityConfig war, dass Spring Boots OAuth2-Resource-Server-Autokonfiguration das OIDC-Discovery-Dokument blockierend beim Start abruft und die Anwendung ohne erreichbaren Issuer deshalb gar nicht erst hochfaehrt - analog zur bewussten Ausnahme vom sonstigen "lauffaehig ohne externe Abhaengigkeit"-Prinzip (Oracle/DB2/Kafka haben alle einen lokalen Fallback: H2 statt Oracle, initializationFailTimeout(-1) fuer DB2).

Ein echter Test (Keycloak-Container gestoppt, Anwendung neu gestartet) widerlegte diese Annahme: Spring Boot 3.2 baut den JwtDecoder bei issuer-uri-Konfiguration ueber einen SupplierJwtDecoder, der das Discovery-Dokument erst beim ersten tatsaechlichen Decodierversuch abruft, nicht beim Kontextstart. Real verifiziert:

Das Verhalten liegt damit tatsaechlich naeher am uebrigen Projekt-Prinzip als urspruenglich angenommen - nur mit dem unveraendert gueltigen Unterschied, dass ohne erreichbaren Identity Provider niemand erfolgreich authentifiziert werden kann.

Real gefundener Bug: Keycloak 24 lehnt Login mit "Account is not fully set up" ab

Beim ersten echten Token-Abruf gegen den frisch importierten Realm schlug der Password-Grant fuer alle drei Testnutzer mit invalid_grant / "Account is not fully set up" fehl, obwohl Nutzer, Passwoerter und Rollen korrekt importiert waren (per Admin-REST-API bestaetigt: Credential vorhanden, requiredActions: []). Server-Log zeigte den eigentlichen Fehler: error="resolve_required_actions". Ursache: Keycloak 24 aktiviert standardmaessig eine User-Profile-Validierung, die fuer die Rolle user ein email-Attribut erfordert (users/profile-Konfiguration, "required": {"roles": ["user"]} fuer email) - die importierten Nutzer hatten keine E-Mail-Adresse, wodurch Keycloak dynamisch eine VERIFY_PROFILE-Required-Action ergaenzte, die den Password-Grant blockierte, ohne dass dies in requiredActions des Nutzers sichtbar wurde. Behoben durch Ergaenzen von email/emailVerified: true/firstName/lastName fuer alle drei Nutzer in novaris-realm.json (und per Admin-REST-API am bereits laufenden Test-Container nachgezogen) - kein Konfigurationsfehler auf Anwendungsseite, sondern ein Keycloak-Default, der bei minimalen Realm-Exports leicht uebersehen wird.

Wie getestet

Real gegen einen laufenden Keycloak-24-Container (quay.io/keycloak/keycloak:24.0 start-dev --import-realm) verifiziert, keine Mocks:

  1. Fuer alle drei Testnutzer echte JWTs per Password-Grant (/realms/novaris/protocol/openid-connect/token) bezogen.
  2. novaris-policy-core-modern gegen den echten Issuer gebootet (bestaetigt: die OIDC-Discovery-Abfrage beim Start gelingt).
  3. Vollstaendige Autorisierungsmatrix mit echten Bearer-Tokens gegen PolicyController verifiziert: - kein Token, GET /api/policies -> 401 - csr-Token, POST /api/policies (nur PolicyAdmin/Underwriter) -> 403 - underwriter-Token, GET /api/policies -> 200 - underwriter-Token, POST /api/policies mit gueltigem Produktcode -> 201, echte Police in H2 angelegt (JPA-Schreibpfad inklusive der @Primary-DataSource-Klaerung aus 09-offene-punkte-geschlossen.md bestaetigt weiterhin funktionsfaehig) - underwriter-Token, POST /{policyNumber}/cancel (nur PolicyAdmin) -> 403 - admin-Token, POST /{policyNumber}/cancel -> 204 - ungueltiger/erfundener Bearer-Token -> 401

Dieselbe Pruefrigorositaet wie bereits fuer die HTTP-Basic-Implementierung in M4 angewendet - nur curl -u user:pass durch curl -H "Authorization: Bearer $TOKEN" ersetzt.

Ehrliche Grenze (Stand nach novaris-policy-web-modern-spa)

Der urspruengliche Stand dieses Dokuments beschrieb kein Frontend-Login als offene Luecke - mittlerweile geschlossen: novaris-policy-web-modern-spa implementiert den Authorization-Code-Flow mit PKCE gegen genau diesen Keycloak-Realm (siehe dessen README, Abschnitt "Real verifiziert"). Weiterhin offen: kein Refresh-Token-Flow (bei Token-Ablauf muss sich die Nutzerin erneut einloggen statt automatisch verlaengert zu werden) - fuer dieses Lernprojekt bewusst nicht gebaut, waere aber der naheliegende naechste Schritt.

⌂ Cockpit