Keycloak UI Customization and Frontend Route Protection
Date: 2025-04-21 Participants: AI Assistant, Rakesh Gangwar
Context
Following the initial Keycloak integration (Phase 1), the standard Keycloak login page redirect felt disconnected from the application's UI (built with shadcn-svelte). There was also a need to protect frontend routes, ensuring only authenticated users could access certain parts of the application.
Discussion & Decisions
-
Custom Login Page vs. Theming:
- Initially explored creating a fully custom login form within the Svelte application using shadcn components (
/loginroute,LoginForm.svelte). - This approach required collecting username/password directly, implying the use of the Resource Owner Password Credentials (ROPC) grant type in Keycloak.
- Recognized the security risks associated with ROPC (application handling passwords) and decided against it.
- Decision: Opted to use the standard OIDC redirect flow but customize Keycloak's login page appearance using Keycloak Theming to match the application's shadcn look and feel.
- Initially explored creating a fully custom login form within the Svelte application using shadcn components (
-
Keycloak Theme Implementation:
- Created a new theme directory:
keycloak/themes/shadcn-theme/. - Configured
theme.propertiesto inherit from the base Keycloak theme and include custom CSS. - Added placeholder CSS (
custom-shadcn.css) with initial styles. - Created a
keycloak/Dockerfileto build a custom Keycloak image containing theshadcn-theme. - Modified
backend/docker-compose.ymlto build and use this custom Keycloak image instead of the official one. - Iteratively refined
custom-shadcn.cssby adding specific selectors and!importantflags to:- Hide the default Keycloak logo (
#kc-logo,#kc-logo-wrapper,#kc-header,#kc-header-wrapper). - Remove the default background image and set a plain background color (
html,body,.login-pf-page, etc.). - Vertically center the login card using Flexbox on the page container.
- Hide the default Keycloak logo (
- Created a new theme directory:
-
Frontend Route Protection:
- Decision: Implement route protection within SvelteKit's layout system.
- Created
frontend/src/routes/+layout.ts. - Added a
loadfunction that runs in the browser. - The
loadfunction checks the authentication status using theuserstore fromauthService.ts. - If the user is not authenticated (
!$user) and the requested route is not in a predefinedpublicRouteslist (/,/login,/callback, etc.), it throws aredirect(307, '/login').
-
UI Enhancements & Fixes:
- Refactored
AuthStatus.svelteto use shadcn-svelte components (Button,Avatar,DropdownMenu) for a more integrated look. - Conditionally rendered the
AppSidebarinfrontend/src/routes/+layout.sveltebased on the$userstore, hiding it for unauthenticated users. - Resolved several Svelte 5 / TypeScript / shadcn-svelte integration issues:
- Used
onclickprop instead ofon:clickdirective for event handling on some shadcn components. - Removed problematic
asChildandbuildersprops fromDropdownMenu.Triggerwhen used with a nestedButton. - Removed comments within component tags that were causing Svelte parser errors.
- Used
- Refactored
-
Authentication UI Improvements:
- Decision: Improved the authentication UI to better integrate with the overall interface.
- Modified
AuthStatus.svelteto only show the login button on the root page when logged out. - Positioned the login button on the right side of the "Last Updated" message in the header.
- Made "Last Updated" message, SidebarTrigger, and Separator only visible when the user is logged in.
- Removed the logout functionality from the header and exclusively used the logout button in the sidebar navigation (
nav-user.svelte). - Updated
app-sidebar.svelteto use the actual user data from the auth service instead of mock data. - Created a derived store in
app-sidebar.sveltethat formats the user data to be compatible with the NavUser component. - Removed redundant AuthStatus components from the layout to avoid duplication.
Next Steps
- Continue refining the CSS in
keycloak/themes/shadcn-theme/login/resources/css/custom-shadcn.cssto fully match the application's shadcn theme (fonts, colors, spacing, input styles, card styles, etc.). - Thoroughly test route protection across different scenarios (direct navigation, refresh, login/logout).
- Consider adding a custom logo to the Keycloak theme.
- Implement a loading state for authentication to improve user experience during login/logout operations.
References
- Keycloak Theming Documentation
docs/logs/devlogs/2025-04-21-keycloak-implementation-strategy.mddocs/logs/devlogs/2025-04-21-keycloak-phase1-implementation.md