From c094fdd25bd6fb65d7816d2eb78e6695faf6793f Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 14 Jun 2025 16:17:58 +0200 Subject: [PATCH] CRITICAL FIX: Enhanced OIDC session configuration for Keycloak authentication ## **Session Management Improvements:** ### **OIDC Configuration (nuxt.config.ts):** - Added proper session configuration with automatic refresh - Configured secure cookies for HTTPS production environment - Added OAuth scopes: ['openid', 'profile', 'email'] - Set proper response type and grant type for Keycloak - Added session expiration checking and automatic refresh ### **Session Cookie Settings:** - sameSite: 'lax' - Required for cross-domain OAuth redirects - secure: true - Required for HTTPS in production - expirationThreshold: 60 - Refresh tokens 60 seconds before expiry ### **Debug Tools:** - Added /api/debug/oidc-session endpoint to monitor session state - Tracks cookie presence and session establishment - Safe debugging without exposing sensitive tokens ## **Problem Being Solved:** User authentication succeeds with Keycloak but session expires immediately, causing redirect back to login page instead of dashboard access. ## **Root Cause Analysis:** - Sessions were not being established properly after OAuth callback - Cookie configuration was not optimized for HTTPS/production - Missing proper OAuth scopes and session refresh configuration ## **Expected Results:** Successful Keycloak authentication should now persist session Users should be redirected to dashboard after login Sessions should automatically refresh before expiry No more immediate redirects back to login page ## **Next Steps:** 1. Rebuild container in Portainer with these session fixes 2. Test authentication flow end-to-end 3. Use debug endpoint to verify session establishment 4. Monitor container logs for OIDC session activity --- nuxt.config.ts | 13 +++++++++++++ server/api/debug/oidc-session.ts | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 server/api/debug/oidc-session.ts diff --git a/nuxt.config.ts b/nuxt.config.ts index ef070e3..46cd7bb 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -115,6 +115,15 @@ export default defineNuxtConfig({ middleware: { globalMiddlewareEnabled: false, // Disable automatic middleware - prevents redirect loops! }, + session: { + expirationCheck: true, + automaticRefresh: true, + expirationThreshold: 60, // seconds before expiry to refresh + cookie: { + sameSite: 'lax', // Required for cross-domain redirects + secure: true // Required for HTTPS in production + } + }, providers: { keycloak: { audience: 'account', @@ -126,6 +135,10 @@ export default defineNuxtConfig({ logoutRedirectUri: 'https://client.portnimara.dev', validateAccessToken: false, // Disable for Keycloak compatibility exposeIdToken: true, + // Additional session settings for Keycloak + scope: ['openid', 'profile', 'email'], + responseType: 'code', + grantType: 'authorization_code' } } }, diff --git a/server/api/debug/oidc-session.ts b/server/api/debug/oidc-session.ts new file mode 100644 index 0000000..143304e --- /dev/null +++ b/server/api/debug/oidc-session.ts @@ -0,0 +1,32 @@ +export default defineEventHandler(async (event) => { + try { + // Get cookies to check session state + const cookies = parseCookies(event) || {} + + // Check for OIDC-related cookies + const oidcCookies = Object.keys(cookies).filter(name => + name.includes('nuxt') || name.includes('oidc') || name.includes('session') + ) + + return { + success: true, + timestamp: new Date().toISOString(), + cookies: { + count: oidcCookies.length, + names: oidcCookies, + hasSession: oidcCookies.some(name => name.includes('session')) + }, + headers: { + host: getHeader(event, 'host'), + userAgent: getHeader(event, 'user-agent'), + referer: getHeader(event, 'referer') + } + } + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + timestamp: new Date().toISOString() + } + } +})