Keycloak Phase 1 Implementation & Debugging
Date: 2025-04-21 Participants: Rakesh Gangwar, AI Assistant
Context
Following the decision in 2025-04-21-keycloak-implementation-strategy.md to implement Keycloak from the start, this session focused on Phase 1: Core Authentication setup. The goal was to integrate Keycloak with the FastAPI backend and SvelteKit frontend using Docker Compose.
Implementation Steps
- Docker Compose Setup: Added Keycloak service definition to
backend/docker-compose.yml. - Backend Integration (FastAPI):
- Added
fastapi-keycloakdependency. - Created
backend/app/core/auth.pywith Keycloak configuration and initialization. - Added a protected route (
/protected) inbackend/app/main.pyusing Keycloak dependency injection. - Created
backend/Dockerfileand fixed build issues (uv pip sync --system).
- Added
- Frontend Integration (SvelteKit):
- Added
oidc-client-tsdependency. - Created
frontend/src/lib/auth/authService.tswithUserManagerconfiguration, user store, and auth functions (login,logout,handleCallback,getAccessToken). - Created
frontend/src/lib/components/auth/AuthStatus.svelteto display login status and provide login/logout buttons. - Created
frontend/src/routes/callback/+page.svelteto handle the OIDC redirect. - Added
AuthStatuscomponent to the main layout (frontend/src/routes/+layout.svelte). - Added
frontend/static/silent-renew.htmland configuredsilent_redirect_uriinauthService.ts.
- Added
Debugging Issues & Solutions
Several issues were encountered during testing:
-
Backend Docker Build Failure: The initial
docker-compose upfailed becausebackend/Dockerfilewas empty. A basic Dockerfile was created. A subsequent failure occurred becauseuv pip syncrequires the--systemflag when not in a virtual environment.- Solution: Added
--systemflag toRUN uv pip sync --system pyproject.tomlinbackend/Dockerfile.
- Solution: Added
-
Frontend SSR Error (
window is not defined): Theoidc-client-tslibrary attempted to accesswindow.localStorageduring server-side rendering.- Solution: Modified
frontend/src/lib/auth/authService.tsto useif (browser)checks, conditionally initializing theUserManagerand accessingwindowonly on the client-side. Explicitly typedkeycloakSettingswithUserManagerSettings.
- Solution: Modified
-
Endless Token/Userinfo Calls & "User loaded" Logs: After login, the frontend made continuous calls to Keycloak's
/tokenand/userinfoendpoints, and the console filled with "User loaded" messages.- Attempt 1: Simplified
getAccessTokeninauthService.tsto rely solely onuserManager.getUser()and removed manualsigninSilent()fromaddAccessTokenExpiredevent handler. (No effect) - Attempt 2: Disabled
loadUserInfo: trueinauthService.ts. (Stopped/userinfocalls, but/tokenloop persisted) - Attempt 3: Refactored
AuthStatus.svelteto use Svelte'sderivedstores. (No effect) - Attempt 4: Added dedicated
silent_redirect_uriandsilent-renew.html. (No effect) - Attempt 5: Disabled
monitorSession: trueinauthService.ts. (No effect) - Attempt 6: Disabled
automaticSilentRenew: falseinauthService.ts. - Solution: Disabling
automaticSilentRenewstopped the loop. This indicates the root cause is likely related to the automatic renewal process interacting incorrectly with the current setup or Keycloak configuration (e.g., token lifespans).
- Attempt 1: Simplified
-
Callback Page Stuck: The
/callbackpage displayed "Login successful! Redirecting..." but did not navigate away.- Initial Attempt: Used SvelteKit's
goto('/')inhandleCallback. This did not work as expected. - Solution (Temporary): Reverted redirection logic in
handleCallbackto usewindow.location.href = '/'. This successfully redirected the user. The reasongotofailed needs further investigation, butwindow.location.hrefis acceptable for now.
- Initial Attempt: Used SvelteKit's
Current Status & Next Steps
- Basic login/logout flow is functional.
- The token renewal loop is stopped by disabling
automaticSilentRenew. - Redirection from the callback page works using
window.location.href.
Immediate Next Steps:
- Restore
gotoNavigation: Revert the temporarywindow.location.hrefback togoto('/')inauthService.tsand investigate why it initially failed. Ensure thegotoimport is present. - Investigate
automaticSilentRenew: Research whyautomaticSilentRenew: truecauses a loop. Check Keycloak token lifespans (Access Token, Refresh Token, SSO Session Idle/Max) and compareoidc-client-tssettings against Keycloak best practices. Re-enableautomaticSilentRenewonce the root cause is found and fixed. - Manual Keycloak Config: Ensure Keycloak clients (
fastapi-client,svelte-client) are correctly configured with appropriate redirect URIs (including/callbackand/silent-renew.html) and settings (client auth for backend, public for frontend). - Update Secrets: Replace placeholder client secret in
backend/app/core/auth.py.
References
docs/logs/devlogs/2025-04-21-keycloak-implementation-strategy.mdfrontend/src/lib/auth/authService.tsfrontend/src/routes/callback/+page.sveltebackend/Dockerfile