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
This commit is contained in:
Matt 2025-06-14 16:17:58 +02:00
parent 12403233c0
commit c094fdd25b
2 changed files with 45 additions and 0 deletions

View File

@ -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'
}
}
},

View File

@ -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()
}
}
})