204 lines
5.1 KiB
Markdown
204 lines
5.1 KiB
Markdown
|
|
# Keycloak Integration Documentation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
This document describes the dual authentication system implementation that supports both Keycloak (new) and Directus (existing) authentication methods running in parallel.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
### Authentication Flow
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
graph TD
|
||
|
|
A[User visits Portal] --> B{Already Authenticated?}
|
||
|
|
B -->|No| C[Login Page]
|
||
|
|
B -->|Yes| D[Dashboard]
|
||
|
|
|
||
|
|
C --> E{Login Method}
|
||
|
|
E -->|SSO Button| F[Redirect to Keycloak]
|
||
|
|
E -->|Email/Password| G[Directus Authentication]
|
||
|
|
|
||
|
|
F --> H[Keycloak Login Page]
|
||
|
|
H --> I[User Authenticates]
|
||
|
|
I --> J[Redirect to /auth/callback]
|
||
|
|
J --> D
|
||
|
|
|
||
|
|
G --> K[Validate with Directus]
|
||
|
|
K --> D
|
||
|
|
```
|
||
|
|
|
||
|
|
### Key Components
|
||
|
|
|
||
|
|
1. **Unified Authentication Composable** (`composables/useUnifiedAuth.ts`)
|
||
|
|
- Provides a single interface for both auth systems
|
||
|
|
- Maps user data to a common format
|
||
|
|
- Handles logout for both systems
|
||
|
|
|
||
|
|
2. **Authentication Middleware** (`middleware/authentication.ts`)
|
||
|
|
- Checks Keycloak auth first, then Directus
|
||
|
|
- Supports public pages via `auth: false` page meta
|
||
|
|
|
||
|
|
3. **Login Page** (`pages/login.vue`)
|
||
|
|
- Dual login options (SSO and traditional)
|
||
|
|
- Public page (no auth required)
|
||
|
|
|
||
|
|
4. **OAuth Callback** (`pages/auth/callback.vue`)
|
||
|
|
- Handles Keycloak OAuth redirects
|
||
|
|
- Shows loading state during authentication
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
### Environment Variables
|
||
|
|
|
||
|
|
```env
|
||
|
|
# Keycloak Configuration
|
||
|
|
KEYCLOAK_ISSUER=https://auth.portnimara.dev/realms/client-portal
|
||
|
|
KEYCLOAK_CLIENT_ID=client-portal
|
||
|
|
KEYCLOAK_CLIENT_SECRET=your-client-secret
|
||
|
|
KEYCLOAK_CALLBACK_URL=https://client.portnimara.dev/auth/callback
|
||
|
|
|
||
|
|
# OIDC Session Configuration
|
||
|
|
OIDC_SESSION_SECRET=your-32-character-session-secret
|
||
|
|
OIDC_ENCRYPT_KEY=your-32-character-encryption-key
|
||
|
|
OIDC_ENCRYPT_IV=16-char-enc-iv!
|
||
|
|
```
|
||
|
|
|
||
|
|
### Keycloak Client Configuration
|
||
|
|
|
||
|
|
1. **Client Type**: Confidential (uses client secret)
|
||
|
|
2. **Authentication Flow**: Standard flow (Authorization Code)
|
||
|
|
3. **Valid Redirect URIs**:
|
||
|
|
- `https://client.portnimara.dev/*`
|
||
|
|
- `https://client.portnimara.dev/auth/callback`
|
||
|
|
- `http://localhost:3000/*` (development)
|
||
|
|
- `http://localhost:3000/auth/callback` (development)
|
||
|
|
4. **Web Origins**: `+` (all redirect URI origins)
|
||
|
|
|
||
|
|
### User Attributes
|
||
|
|
|
||
|
|
Custom Keycloak attributes:
|
||
|
|
- `tier`: User tier level (basic, premium, admin)
|
||
|
|
|
||
|
|
Standard attributes used:
|
||
|
|
- `email`: User email address
|
||
|
|
- `given_name` / `firstName`: First name
|
||
|
|
- `family_name` / `lastName`: Last name
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
|
||
|
|
### For Components
|
||
|
|
|
||
|
|
Replace Directus-specific code with unified auth:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// Before
|
||
|
|
const user = useDirectusUser();
|
||
|
|
const { logout } = useDirectusAuth();
|
||
|
|
|
||
|
|
// After
|
||
|
|
const { user, logout } = useUnifiedAuth();
|
||
|
|
```
|
||
|
|
|
||
|
|
### User Object Structure
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface UnifiedUser {
|
||
|
|
id: string; // User ID
|
||
|
|
email: string; // Email address
|
||
|
|
name: string; // Full name
|
||
|
|
tier?: string; // User tier (basic, premium, admin)
|
||
|
|
authSource: 'keycloak' | 'directus'; // Auth system used
|
||
|
|
raw: any; // Original user object
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Checking Authentication
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
const { isAuthenticated, authSource, isAdmin } = useUnifiedAuth();
|
||
|
|
|
||
|
|
if (isAuthenticated.value) {
|
||
|
|
console.log(`User logged in via ${authSource.value}`);
|
||
|
|
|
||
|
|
if (isAdmin.value) {
|
||
|
|
// Show admin features
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
### Test Page
|
||
|
|
|
||
|
|
Visit `/dashboard/auth-test` to:
|
||
|
|
- View current authentication status
|
||
|
|
- See user information and tier
|
||
|
|
- Test logout functionality
|
||
|
|
- View raw user data
|
||
|
|
|
||
|
|
### Testing Both Auth Methods
|
||
|
|
|
||
|
|
1. **Directus Login**:
|
||
|
|
- Use email/password form on login page
|
||
|
|
- Existing users continue to work
|
||
|
|
|
||
|
|
2. **Keycloak Login**:
|
||
|
|
- Click "Login with Single Sign-On"
|
||
|
|
- Redirected to Keycloak
|
||
|
|
- Returns to portal after authentication
|
||
|
|
|
||
|
|
## Migration Path
|
||
|
|
|
||
|
|
### Phase 1: Parallel Systems (Current)
|
||
|
|
- Both authentication methods available
|
||
|
|
- Users can choose their preferred method
|
||
|
|
- No breaking changes
|
||
|
|
|
||
|
|
### Phase 2: Gradual Migration
|
||
|
|
- Encourage SSO usage
|
||
|
|
- Migrate users to Keycloak
|
||
|
|
- Monitor adoption rates
|
||
|
|
|
||
|
|
### Phase 3: Keycloak Only
|
||
|
|
- Remove Directus login option
|
||
|
|
- All users on Keycloak
|
||
|
|
- Simplified codebase
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Common Issues
|
||
|
|
|
||
|
|
1. **"Invalid redirect URI" error**
|
||
|
|
- Check Keycloak client redirect URIs
|
||
|
|
- Ensure callback URL matches environment
|
||
|
|
|
||
|
|
2. **User tier not showing**
|
||
|
|
- Verify tier attribute in Keycloak
|
||
|
|
- Check attribute mappers in client scope
|
||
|
|
|
||
|
|
3. **Name not displaying correctly**
|
||
|
|
- Ensure firstName/lastName set in Keycloak
|
||
|
|
- Check unified auth name construction logic
|
||
|
|
|
||
|
|
### Debug Mode
|
||
|
|
|
||
|
|
Enable debug logging in development:
|
||
|
|
- OIDC debug mode automatically enabled
|
||
|
|
- Check browser console for auth flow details
|
||
|
|
- Review network tab for OAuth redirects
|
||
|
|
|
||
|
|
## Security Considerations
|
||
|
|
|
||
|
|
1. **Client Secret**: Never expose in client-side code
|
||
|
|
2. **Session Security**: Uses encrypted cookies
|
||
|
|
3. **Token Validation**: Server-side APIs should validate JWTs
|
||
|
|
4. **HTTPS Required**: OAuth flow requires secure connections
|
||
|
|
|
||
|
|
## Future Enhancements
|
||
|
|
|
||
|
|
- [ ] Social login providers (Google, Microsoft)
|
||
|
|
- [ ] Multi-factor authentication
|
||
|
|
- [ ] User self-service portal
|
||
|
|
- [ ] Advanced role-based access control
|
||
|
|
- [ ] Session management UI
|