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:
parent
12403233c0
commit
c094fdd25b
|
|
@ -115,6 +115,15 @@ export default defineNuxtConfig({
|
||||||
middleware: {
|
middleware: {
|
||||||
globalMiddlewareEnabled: false, // Disable automatic middleware - prevents redirect loops!
|
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: {
|
providers: {
|
||||||
keycloak: {
|
keycloak: {
|
||||||
audience: 'account',
|
audience: 'account',
|
||||||
|
|
@ -126,6 +135,10 @@ export default defineNuxtConfig({
|
||||||
logoutRedirectUri: 'https://client.portnimara.dev',
|
logoutRedirectUri: 'https://client.portnimara.dev',
|
||||||
validateAccessToken: false, // Disable for Keycloak compatibility
|
validateAccessToken: false, // Disable for Keycloak compatibility
|
||||||
exposeIdToken: true,
|
exposeIdToken: true,
|
||||||
|
// Additional session settings for Keycloak
|
||||||
|
scope: ['openid', 'profile', 'email'],
|
||||||
|
responseType: 'code',
|
||||||
|
grantType: 'authorization_code'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Loading…
Reference in New Issue