Authentification & autorisation
ADB utilise Keycloak comme fournisseur d'identité unique (SSO + OAuth2). Tous les services Java sont des resource servers OAuth2 et valident eux-mêmes les JWT.
Topologie
flowchart LR
User[Utilisateur]
UI[adb-ui<br/>ou<br/>adb-web/ui]
KC[Keycloak<br/>realm ADB]
BFF[adb-web/bff]
GW[adb/proxy<br/>Nginx]
Svc[Microservice Java]
User -->|1. login| UI
UI -->|2. redirect| KC
KC -->|3. auth flow| User
User -->|4. credentials| KC
KC -->|5. JWT| UI
UI -->|6. Bearer JWT| BFF
BFF -->|7. valide JWT| KC
BFF -->|8. forward JWT| GW
GW --> Svc
Svc -->|valide JWT<br/>via JWKS| KC
Realm Keycloak
- URL :
https://dev-security.life-connect.fr/realms/ADB(dev) - Issuer URI propagée via la variable
SECURITY_ISSUER_URI - Token endpoint :
SECURITY_TOKEN_URI
Clients OAuth2
| Client | Type | Usage |
|---|---|---|
| Frontend (UI) | public | Authorization Code flow + PKCE |
| Service-to-service | confidential | Client Credentials flow (chaque service a son CLIENT_ID / CLIENT_SECRET) |
| Admin client | confidential | Provisioning d'utilisateurs depuis adb-persons (variables ADMIN_CLIENT_ID / ADMIN_CLIENT_SECRET) |
Flux côté frontend
adb-ui (Angular legacy)
Utilise keycloak-angular (v19.0.2) + keycloak-js (v22.0.5). Configuration dans src/environments/environment.*.ts :
keycloak: {
issuer: '...',
realm: 'ADB',
clientId: '...',
redirectUri: '...',
}
Un AuthGuard protège les routes ; le JWT est ajouté automatiquement aux requêtes via un HttpInterceptor.
adb-web/apps/bff
Le BFF Hono (en cours de construction) doit :
- Valider le JWT à l'edge (clé publique Keycloak via JWKS).
- Extraire l'utilisateur et les rôles.
- Forwarder la requête au backend Java en conservant le
Authorization: Bearer ...(pour que le service Java refasse sa propre validation, défense en profondeur).
Secret Cloudflare : JWT_SECRET (TODO côté wrangler.jsonc).
Flux côté backend
Chaque service Spring déclare le starter spring-boot-starter-oauth2-resource-server et configure :
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: ${SECURITY_ISSUER_URI}
La vérification est stateless : pas d'appel à Keycloak par requête, seulement via le JWKS récupéré au démarrage.
Provisioning d'utilisateurs
adb-persons est le seul service qui écrit dans Keycloak (création de comptes, gestion des rôles via InvitationController). Il utilise un client admin avec scope realm-management.
Variables d'environnement par service
| Variable | Rôle |
|---|---|
SECURITY_ISSUER_URI | Issuer Keycloak (validation JWT) |
SECURITY_TOKEN_URI | Endpoint token (Client Credentials pour appels service-to-service) |
CLIENT_ID / CLIENT_SECRET | Credentials du service (pour appels sortants vers d'autres services) |
ADMIN_CLIENT_ID / ADMIN_CLIENT_SECRET | (adb-persons uniquement) Provisioning Keycloak |
Charts / secrets Kubernetes
Les credentials sont injectés via adb-charts/charts/security/ (UAA legacy + scopes OAuth) et les Secret Kubernetes par environnement (values-dev.yaml, values-prod.yaml, etc.).
Notes
- Pas de session côté serveur : tout est stateless, le JWT contient l'identité et les rôles.
- Refresh token : géré par
keycloak-jscôté navigateur. - Logout : appel à l'endpoint
end_session_endpointde Keycloak + invalidation du token côté UI.