This commit is contained in:
Matthias Hochmeister
2026-02-23 17:08:58 +01:00
commit f09748f4a1
97 changed files with 17729 additions and 0 deletions

609
AUTHENTIK_SETUP.md Normal file
View File

@@ -0,0 +1,609 @@
# Authentik Setup Guide
This guide walks you through configuring Authentik for OAuth 2.0 / OpenID Connect authentication with the Feuerwehr Dashboard.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Authentik Installation](#authentik-installation)
- [Creating the Application](#creating-the-application)
- [Provider Configuration](#provider-configuration)
- [Redirect URIs Setup](#redirect-uris-setup)
- [Scopes Configuration](#scopes-configuration)
- [Getting Client Credentials](#getting-client-credentials)
- [Testing Authentication](#testing-authentication)
- [Common Issues](#common-issues)
- [Advanced Configuration](#advanced-configuration)
## Prerequisites
Before you begin, you need:
- An Authentik instance (self-hosted or cloud)
- Admin access to Authentik
- Your Feuerwehr Dashboard URL (e.g., `https://dashboard.yourdomain.com`)
- Your backend API URL (e.g., `https://api.yourdomain.com`)
## Authentik Installation
If you don't have Authentik yet, here's a quick setup guide.
### Option 1: Docker Compose (Recommended)
Create `docker-compose.yml`:
```yaml
version: "3.8"
services:
postgresql:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-authentik}
POSTGRES_DB: ${PG_DB:-authentik}
env_file:
- .env
redis:
image: redis:alpine
restart: unless-stopped
server:
image: ghcr.io/goauthentik/server:2024.2
restart: unless-stopped
command: server
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_REDIS__HOST: redis
ports:
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
depends_on:
- postgresql
- redis
worker:
image: ghcr.io/goauthentik/server:2024.2
restart: unless-stopped
command: worker
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_REDIS__HOST: redis
depends_on:
- postgresql
- redis
volumes:
database:
driver: local
```
Create `.env`:
```bash
PG_PASS=<secure-database-password>
AUTHENTIK_SECRET_KEY=<generate-with-openssl-rand-base64-32>
AUTHENTIK_PORT_HTTP=9000
AUTHENTIK_PORT_HTTPS=9443
```
Start Authentik:
```bash
docker-compose up -d
```
Access Authentik at `http://localhost:9000` and complete the initial setup wizard.
### Option 2: Kubernetes
See [Authentik Kubernetes Documentation](https://goauthentik.io/docs/installation/kubernetes) for Helm charts.
## Creating the Application
### Step 1: Access Authentik Admin Interface
1. Log in to your Authentik instance
2. Navigate to **Admin Interface** (gear icon in top right)
### Step 2: Create Provider
1. In the admin panel, go to **Applications****Providers**
2. Click **Create** button
3. Select **OAuth2/OpenID Provider**
Configure the provider:
```
Name: Feuerwehr Dashboard Provider
Authorization Flow: default-provider-authorization-implicit-consent
Protocol Settings:
```
**Client Type**:
- Select: `Confidential`
**Client ID**:
- Auto-generated (you'll copy this later)
- Or set custom: `feuerwehr-dashboard`
**Client Secret**:
- Auto-generated (you'll copy this later)
**Redirect URIs**:
```
http://localhost:5173/auth/callback
http://localhost/auth/callback
https://dashboard.yourdomain.com/auth/callback
```
Add one URI per line. Include all environments (development, staging, production).
**Signing Key**:
- Select: `authentik Self-signed Certificate` (default)
**Token Validity**:
```
Access token validity: 3600 (1 hour)
Refresh token validity: 86400 (24 hours)
```
Click **Create** to save the provider.
### Step 3: Create Application
1. Go to **Applications****Applications**
2. Click **Create** button
Configure the application:
```
Name: Feuerwehr Dashboard
Slug: feuerwehr-dashboard
Provider: Feuerwehr Dashboard Provider (select from dropdown)
Launch URL: https://dashboard.yourdomain.com
```
**UI Settings** (optional):
```
Icon: (upload fire department logo)
Publisher: Your Fire Department Name
Description: Fire department operations dashboard
```
Click **Create** to save.
### Step 4: Configure Scopes
1. Go back to **Providers****Feuerwehr Dashboard Provider**
2. Scroll to **Advanced protocol settings**
3. Click **Edit** on **Scopes**
Ensure the following scopes are selected:
- [x] `openid` - Required for OpenID Connect
- [x] `profile` - User profile information
- [x] `email` - User email address
Optional scopes:
- [ ] `offline_access` - For refresh tokens (recommended)
Click **Update**.
## Provider Configuration
### Step 5: Configure Advanced Settings
Edit your provider and configure these advanced settings:
**Token Settings**:
```
Include claims in ID token: Yes
Access token validity: 3600 seconds (1 hour)
Refresh token validity: 86400 seconds (24 hours)
```
**Subject Mode**:
```
Based on the User's hashed ID
```
This ensures consistent user IDs.
**Signing Algorithm**:
```
RS256 (default)
```
### Step 6: Configure Claims
Ensure the following claims are mapped:
Standard claims (should be automatic):
- `sub` - Subject (user ID)
- `email` - User email
- `name` - Full name
- `preferred_username` - Username
- `given_name` - First name
- `family_name` - Last name
These are automatically included with the `profile` and `email` scopes.
## Redirect URIs Setup
Your redirect URIs must match exactly between Authentik and your application.
### Development Environment
```
http://localhost:5173/auth/callback
```
This is the Vite dev server URL.
### Production Environment
```
https://dashboard.yourdomain.com/auth/callback
```
Replace `yourdomain.com` with your actual domain.
### Docker Local Testing
```
http://localhost/auth/callback
http://localhost:80/auth/callback
```
For testing the production Docker build locally.
### Important Notes
- URLs are **case-sensitive**
- Must include protocol (`http://` or `https://`)
- No trailing slashes
- Port numbers must match if specified
## Scopes Configuration
### Required Scopes
Your application requires these scopes:
1. **openid** - Identifies this as an OpenID Connect request
2. **profile** - Provides basic profile information
3. **email** - Provides user email address
### Requesting Scopes
The dashboard automatically requests these scopes in the OAuth flow.
Backend configuration (`backend/src/config/oauth.ts`):
```typescript
scopes: ['openid', 'profile', 'email']
```
Frontend login flow (`frontend/src/services/authService.ts`):
```typescript
const scopes = 'openid profile email';
```
## Getting Client Credentials
### Step 7: Copy Client Credentials
1. Go to **Applications****Providers**
2. Click on **Feuerwehr Dashboard Provider**
3. Find the **Client ID** and **Client Secret**
**Client ID**: Will look like `abc123def456...` or custom `feuerwehr-dashboard`
**Client Secret**: Click the **eye icon** to reveal, then **copy button**
### Step 8: Get Provider URLs
1. In the provider details, find **OpenID Configuration URL**:
```
https://auth.yourdomain.com/application/o/feuerwehr-dashboard/.well-known/openid-configuration
```
2. Important URLs from this configuration:
- **Issuer**: `https://auth.yourdomain.com/application/o/feuerwehr-dashboard/`
- **Authorization Endpoint**: Auto-discovered
- **Token Endpoint**: Auto-discovered
- **Userinfo Endpoint**: Auto-discovered
### Step 9: Configure Dashboard
Update your Feuerwehr Dashboard `.env` file:
```bash
# Authentik OAuth Configuration
AUTHENTIK_CLIENT_ID=<your-client-id>
AUTHENTIK_CLIENT_SECRET=<your-client-secret>
AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/
AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback
# For development, use:
# AUTHENTIK_ISSUER=http://localhost:9000/application/o/feuerwehr-dashboard/
# AUTHENTIK_REDIRECT_URI=http://localhost:5173/auth/callback
```
**Important**: The `AUTHENTIK_ISSUER` must end with a trailing slash `/`.
## Testing Authentication
### Step 10: Test the Flow
1. **Start your application**:
```bash
# Development
cd backend && npm run dev
cd frontend && npm run dev
# Or production
make prod
```
2. **Open the dashboard** in your browser:
```
Development: http://localhost:5173
Production: https://dashboard.yourdomain.com
```
3. **Click "Login" button**
4. **You should be redirected to Authentik** login page
5. **Enter your Authentik credentials**
6. **Consent screen** (if enabled):
- Review permissions
- Click "Authorize"
7. **Redirect back to dashboard**:
- Should show your dashboard
- User profile should be loaded
- Check browser console for any errors
### Step 11: Verify Token Exchange
Check backend logs:
```bash
make logs-prod
# or
cd backend && npm run dev
```
Look for:
```
[INFO] OAuth callback received
[INFO] Token exchange successful
[INFO] User authenticated: <username>
```
### Step 12: Test User Profile
In the dashboard:
1. Navigate to Profile page
2. Verify your information is displayed:
- Username
- Email
- Name
### Step 13: Test Logout
1. Click "Logout" button
2. Should redirect to login page
3. Verify session is cleared
4. Attempting to access dashboard should redirect to login
## Common Issues
### Issue 1: Redirect URI Mismatch
**Error**: `redirect_uri_mismatch` or `invalid_redirect_uri`
**Solution**:
1. Check the redirect URI in Authentik **exactly** matches your app
2. Include protocol (`http://` or `https://`)
3. Check for trailing slashes
4. Verify port numbers match
### Issue 2: Invalid Client Credentials
**Error**: `invalid_client`
**Solution**:
1. Verify `AUTHENTIK_CLIENT_ID` is correct
2. Verify `AUTHENTIK_CLIENT_SECRET` is correct (no extra spaces)
3. Check if client secret was regenerated in Authentik
4. Ensure client type is "Confidential"
### Issue 3: CORS Errors
**Error**: CORS policy blocked request
**Solution**:
1. Ensure `CORS_ORIGIN` in backend `.env` matches frontend URL
2. For development: `CORS_ORIGIN=http://localhost:5173`
3. For production: `CORS_ORIGIN=https://dashboard.yourdomain.com`
4. Restart backend after changing CORS settings
### Issue 4: Token Validation Failed
**Error**: `Invalid token` or `Token signature verification failed`
**Solution**:
1. Verify `AUTHENTIK_ISSUER` URL is correct
2. Ensure issuer URL ends with `/`
3. Check Authentik is accessible from backend server
4. Verify JWT signing key hasn't changed
### Issue 5: Scope Errors
**Error**: `invalid_scope` or missing user data
**Solution**:
1. Ensure `openid`, `profile`, `email` scopes are configured in Authentik
2. Check scopes are requested in login flow
3. Verify user has consented to scopes
### Issue 6: User Not Created in Database
**Error**: Authentication works but user not found
**Solution**:
1. Check backend logs for database errors
2. Verify database migrations ran
3. Check `users` table exists:
```bash
docker exec -it feuerwehr_db_prod psql -U prod_user -d feuerwehr_prod -c "\dt"
```
4. Manually run migrations if needed
### Issue 7: Token Refresh Fails
**Error**: Refresh token invalid or expired
**Solution**:
1. Check token validity settings in Authentik
2. Increase refresh token validity (e.g., 86400 seconds)
3. Verify `offline_access` scope is included
4. Clear browser cookies and re-authenticate
## Advanced Configuration
### Customizing Login Flow
Create custom authentication flow in Authentik:
1. Go to **Flows & Stages** → **Flows**
2. Duplicate `default-provider-authorization-implicit-consent`
3. Add custom stages (MFA, email verification, etc.)
4. Update provider to use custom flow
### Adding Multi-Factor Authentication
1. Go to **Flows & Stages** → **Stages**
2. Create authenticator validation stage
3. Add to your authorization flow
4. Users will be prompted for MFA on login
### Branding
Customize Authentik appearance:
1. Go to **System** → **Branding**
2. Upload logo
3. Set primary color to match fire department branding
4. Configure footer links
### User Management
Add users to Authentik:
1. Go to **Directory** → **Users**
2. Click **Create**
3. Fill in user details
4. Set password
5. Assign to groups (if using RBAC)
### Group-Based Access Control
Implement role-based access:
1. Create groups in **Directory** → **Groups**
2. Assign users to groups
3. In your app, read `groups` claim from token
4. Implement authorization based on groups
Example groups:
- `feuerwehr-admin` - Full access
- `feuerwehr-operator` - Standard access
- `feuerwehr-viewer` - Read-only access
## Testing Checklist
After configuration, verify:
- [ ] Login redirects to Authentik
- [ ] Successful authentication redirects back
- [ ] User profile loads correctly
- [ ] Tokens are stored securely
- [ ] Logout clears session
- [ ] Token refresh works
- [ ] Protected routes require authentication
- [ ] Invalid tokens are rejected
- [ ] CORS is properly configured
- [ ] Works on all browsers (Chrome, Firefox, Safari)
## Configuration Reference
### Minimum Required Settings
**Authentik Provider**:
```
Client Type: Confidential
Client ID: <auto-generated>
Client Secret: <auto-generated>
Redirect URIs: https://dashboard.yourdomain.com/auth/callback
Scopes: openid, profile, email
Access Token Validity: 3600
Refresh Token Validity: 86400
```
**Dashboard .env**:
```bash
AUTHENTIK_CLIENT_ID=<from-authentik>
AUTHENTIK_CLIENT_SECRET=<from-authentik>
AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/
AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback
```
## Security Best Practices
1. **Use HTTPS in production** - Never use HTTP for OAuth flows
2. **Keep secrets secret** - Never commit credentials to Git
3. **Rotate secrets regularly** - Change client secrets periodically
4. **Use strong passwords** - For Authentik admin and users
5. **Enable MFA** - Require multi-factor authentication for admin users
6. **Monitor logs** - Watch for failed login attempts
7. **Limit token validity** - Use short-lived access tokens
8. **Validate redirect URIs** - Only allow known URLs
## Additional Resources
- [Authentik Documentation](https://goauthentik.io/docs/)
- [OAuth 2.0 Specification](https://oauth.net/2/)
- [OpenID Connect](https://openid.net/connect/)
- [Authentik Community Forum](https://github.com/goauthentik/authentik/discussions)
## Support
If you encounter issues:
1. Check Authentik logs: `docker-compose logs -f server`
2. Check dashboard backend logs: `make logs-prod`
3. Review browser console for errors
4. Consult [Common Issues](#common-issues) section
5. Search Authentik GitHub issues
6. Create detailed issue report
---
**Next Steps**: After completing Authentik setup, proceed to [DEPLOYMENT.md](DEPLOYMENT.md) for production deployment.