124 lines
4.2 KiB
Markdown
124 lines
4.2 KiB
Markdown
# 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 `refreshToken` to session object
|
|
- Allows API endpoints to refresh tokens when needed
|
|
|
|
## Files Modified
|
|
|
|
1. **`app/api/auth/refresh-keycloak-session/route.ts`** (NEW)
|
|
- API endpoint to refresh Keycloak tokens
|
|
- Uses refresh token to get new access tokens
|
|
|
|
2. **`app/components/responsive-iframe.tsx`**
|
|
- Automatically refreshes session before loading iframe
|
|
- Shows loading indicator during refresh
|
|
|
|
3. **`app/api/auth/options.ts`**
|
|
- Exposes `refreshToken` in session object
|
|
|
|
4. **`types/next-auth.d.ts`**
|
|
- Added `refreshToken` to Session interface
|
|
|
|
## 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:
|
|
1. **OAuth Token Session**: Managed via refresh tokens (what we refresh)
|
|
2. **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:
|
|
|
|
1. Go to Keycloak Admin Console
|
|
2. Navigate to: Realm Settings → Sessions
|
|
3. Set **SSO Session Idle** to match your needs (e.g., 30 days)
|
|
4. 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 `accessToken` via URL parameter: `?token=${accessToken}`
|
|
- Or use `postMessage` to 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
|
|
|
|
1. Log in to dashboard
|
|
2. Wait for Keycloak session to expire (or manually clear Keycloak cookies)
|
|
3. Navigate to an iframe application
|
|
4. Session should be refreshed automatically
|
|
5. Iframe should load without requiring login
|
|
|
|
## Environment Variables Required
|
|
|
|
```bash
|
|
NEXT_PUBLIC_KEYCLOAK_ISSUER=https://keycloak.example.com/realms/neah
|
|
KEYCLOAK_CLIENT_ID=neah-dashboard
|
|
KEYCLOAK_CLIENT_SECRET=<secret>
|
|
```
|
|
|
|
## Future Improvements
|
|
|
|
1. **Implement invisible iframe to Keycloak**: Use Keycloak's check-session-iframe to refresh cookies
|
|
2. **Token passing**: Pass access tokens to iframe applications if they support it
|
|
3. **Proactive refresh**: Implement periodic token refresh to prevent expiration
|
|
4. **Session monitoring**: Monitor Keycloak session status and refresh proactively
|
|
|
|
---
|
|
|
|
**Date**: 2024
|
|
**Status**: ✅ Implemented (with limitations)
|
|
**Version**: 1.0
|
|
|