4.2 KiB
Keycloak Session Synchronization Fix
Problem
When a user is still logged into the NextAuth dashboard (session valid for 30 days), but Keycloak session cookies have expired (typically 30 minutes to a few hours), iframe applications can't authenticate because they rely on Keycloak cookies for SSO.
Symptoms:
- User is logged into dashboard
- Iframe applications ask for Keycloak login again
- NextAuth session is still valid, but Keycloak cookies expired
Root Cause
Session Mismatch:
- NextAuth Session: 30 days (JWT-based, stored in encrypted cookie)
- Keycloak Session Cookies: Typically 30 minutes to a few hours (set by Keycloak server)
- Iframe Applications: Rely on Keycloak session cookies for SSO, not NextAuth tokens
When Keycloak session cookies expire, iframe applications can't authenticate even though NextAuth session is still valid.
Solution Implemented
1. Session Refresh API Endpoint
Created /api/auth/refresh-keycloak-session that:
- Uses the refresh token to get new Keycloak tokens
- Ensures tokens are fresh before loading iframes
- Helps maintain token synchronization
2. Automatic Session Refresh Before Iframe Load
Updated ResponsiveIframe component to:
- Automatically refresh the session before loading iframe applications
- Show a loading indicator during refresh
- Ensure tokens are fresh when iframes load
3. Exposed Refresh Token in Session
- Added
refreshTokento session object - Allows API endpoints to refresh tokens when needed
Files Modified
-
app/api/auth/refresh-keycloak-session/route.ts(NEW)- API endpoint to refresh Keycloak tokens
- Uses refresh token to get new access tokens
-
app/components/responsive-iframe.tsx- Automatically refreshes session before loading iframe
- Shows loading indicator during refresh
-
app/api/auth/options.ts- Exposes
refreshTokenin session object
- Exposes
-
types/next-auth.d.ts- Added
refreshTokento Session interface
- Added
Limitations
Important: This solution refreshes OAuth tokens, but Keycloak session cookies are separate and are set by Keycloak when the user authenticates via the browser. Refreshing OAuth tokens doesn't automatically refresh Keycloak session cookies.
Why This Happens
Keycloak maintains two separate sessions:
- OAuth Token Session: Managed via refresh tokens (what we refresh)
- Browser Session Cookies: Set by Keycloak during login, expire based on Keycloak's session timeout settings
Recommended Solutions
Option 1: Configure Keycloak Session Timeout (Recommended)
Increase Keycloak's SSO session timeout to match or exceed NextAuth's 30-day session:
- Go to Keycloak Admin Console
- Navigate to: Realm Settings → Sessions
- Set SSO Session Idle to match your needs (e.g., 30 days)
- Set SSO Session Max to match (e.g., 30 days)
This ensures Keycloak cookies don't expire before NextAuth session.
Option 2: Pass Access Token to Iframe Applications
If iframe applications support token-based authentication:
- Pass
accessTokenvia URL parameter:?token=${accessToken} - Or use
postMessageto send token to iframe - Iframe applications can then use the token for authentication
Option 3: Periodic Session Refresh
Implement a periodic refresh mechanism that:
- Checks session validity every 15-20 minutes
- Refreshes tokens proactively
- May help keep Keycloak session active
Testing
- Log in to dashboard
- Wait for Keycloak session to expire (or manually clear Keycloak cookies)
- Navigate to an iframe application
- Session should be refreshed automatically
- Iframe should load without requiring login
Environment Variables Required
NEXT_PUBLIC_KEYCLOAK_ISSUER=https://keycloak.example.com/realms/neah
KEYCLOAK_CLIENT_ID=neah-dashboard
KEYCLOAK_CLIENT_SECRET=<secret>
Future Improvements
- Implement invisible iframe to Keycloak: Use Keycloak's check-session-iframe to refresh cookies
- Token passing: Pass access tokens to iframe applications if they support it
- Proactive refresh: Implement periodic token refresh to prevent expiration
- Session monitoring: Monitor Keycloak session status and refresh proactively
Date: 2024
Status: ✅ Implemented (with limitations)
Version: 1.0