Files
familienarchiv/docs/architecture/c4/seq-auth-flow.puml
Marcel 3438260090
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m4s
CI / OCR Service Tests (pull_request) Successful in 20s
CI / Backend Unit Tests (pull_request) Successful in 3m6s
CI / fail2ban Regex (pull_request) Successful in 40s
CI / Semgrep Security Scan (pull_request) Successful in 17s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m0s
docs: rewrite seq-auth-flow.puml for the Spring Session model (ADR-020)
Removes the cookie-promotion step (auth_token → Authorization: Basic) and
splits the diagram into three labelled phases: Login, Authenticated
request, Logout. Adds the spring_session DB round-trip on every
authenticated request and the alt branch for an expired session
returning 401 → /login?reason=expired.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 20:59:44 +02:00

3.2 KiB

Authentication Flow (Spring Session JDBC, behind Caddy reverse proxy)Authentication Flow (Spring Session JDBC, behind Caddy reverse proxy)UserBrowserCaddy .TLS termination.Frontend .SvelteKit.Backend .Spring Boot.DBUserUserBrowserBrowserCaddy (TLS termination)Caddy (TLS termination)Frontend (SvelteKit)Frontend (SvelteKit)Backend (Spring Boot)Backend (Spring Boot)DBDBPhase 1 of the auth rewrite (ADR-020 / #523).Replaces the Basic-credentials-in-cookie modelwith an opaque server-side session id (fa_session).LoginEnter email + passwordHTTPS POST /?/login (form action)Caddy terminates TLS and forwardsto Frontend over HTTP with:X-Forwarded-Proto: httpsX-Forwarded-For: <client IP>X-Forwarded-Host: archiv.raddatz.cloudHTTP POST /?/login + X-Forwarded-Proto: httpsPOST /api/auth/login{email, password}+ X-Forwarded-Proto: httpsserver.forward-headers-strategy: native→ request.getScheme() = "https"→ Secure cookie flag set automatically.AuthenticationManagerauthenticate(email, password)SELECT user WHERE email=?AppUser + groups + permissionsBCrypt.matches(password, hash)(timing-safe: dummy hash on miss)getSession(true).setAttribute(SPRING_SECURITY_CONTEXT, ctx)INSERT spring_session+ spring_session_attributesAuditService.log(LOGIN_SUCCESS,{userId, ip, ua})200 OK — AppUserSet-Cookie: fa_session=<opaque>;Path=/; HttpOnly; SameSite=Strict; SecureParse Set-Cookie, re-emit fa_session(matches backend attrs)303 → /Set-Cookie: fa_session=<opaque>HTTPS 303 + Set-CookieAuthenticated requestHTTPS GET /Cookie: fa_session=<opaque>HTTP GET / + Cookie + X-Forwarded-Proto: httpshooks.server.ts reads fa_sessionGET /api/users/meCookie: fa_session=<opaque>SELECT * FROM spring_sessionWHERE SESSION_ID = ?row (or null if expired)alt[Session valid]UPDATE spring_sessionSET LAST_ACCESS_TIME = now200 OK — AppUserrendered pageHTTPS 200[Session expired (idle > 8h) or unknown]401 Unauthorizedhooks: delete fa_session cookie302 → /login?reason=expiredHTTPS 302LogoutHTTPS POST /logoutHTTP POST /logoutCookie: fa_session=<opaque>POST /api/auth/logoutCookie: fa_session=<opaque>session.invalidate()SecurityContextHolder.clearContext()DELETE FROM spring_sessionWHERE SESSION_ID = ?AuditService.log(LOGOUT,{userId, ip, ua})204 No Contentcookies.delete('fa_session')303 → /loginHTTPS 303 (cookie cleared)