✦ Nouvel article·Ce qu'on devrait vraiment évaluer sur un software engineer en 2026·6 min de lecture·Lire l'article →|✦ Nouvel article·Ce qu'on devrait vraiment évaluer sur un software engineer en 2026·6 min de lecture·Lire l'article →|✦ Nouvel article·Ce qu'on devrait vraiment évaluer sur un software engineer en 2026·6 min de lecture·Lire l'article →|
Tous les articles
28 mars 2026·8 min de lecture

Keycloak OAuth2/OIDC : zéro custom auth, 100% standard

Pourquoi j'ai délégué toute la sécurité à Keycloak plutôt que de coder ma propre authentification.

KeycloakOAuth2OIDCSpring SecurityJWT

La première version de mon auth service avait une table users, un endpoint /login qui générait un JWT maison avec HS256, et un filtre Spring Security qui validait ce token. Ça marchait. C'était aussi une bombe à retardement.

Le problème avec un auth custom

  • Gestion des sessions et refresh tokens : à implémenter manuellement, souvent mal fait
  • Rotation des clés de signature : quand et comment renouveler la clé HS256 en prod ?
  • RBAC granulaire : ajouter des rôles et permissions dans une app custom devient vite un enfer
  • Multi-applications : si demain j'ajoute un front React et une app mobile, chacun refait sa gestion de session
  • Compliance (RGPD, OIDC standard) : les auditeurs veulent des standards, pas du home-made

Keycloak résout tous ces problèmes. C'est un Identity and Access Management (IAM) open-source qui implémente OAuth2 et OpenID Connect (OIDC) selon les RFC. Vous ne codez pas l'auth — vous la configurez.

Le flux OIDC complet

Voici ce qui se passe quand un utilisateur s'inscrit sur ma banking platform :

    1. Client → POST /api/auth/register → bank-auth-service
    1. bank-auth-service → POST /admin/realms/bank/users → Keycloak REST Admin API
    1. Keycloak crée l'utilisateur dans sa base PostgreSQL (authdb)
    1. bank-auth-service publie un événement UserRegistered sur Kafka
    1. notification-service consomme l'événement et envoie l'email de confirmation

Pour la connexion, le client obtient un access token JWT directement depuis Keycloak via le flux Authorization Code ou le flux Resource Owner Password (pour les apps mobiles internes). L'API Gateway valide ce token via les JWKS de Keycloak sans appel réseau supplémentaire.

RS256 plutôt que HS256 : pourquoi c'est important

Avec HS256 (symétrique), tous les services qui valident le token doivent connaître la clé secrète. Si cette clé fuite depuis n'importe lequel de vos 10 services, c'est game over. Avec RS256 (asymétrique), seul Keycloak connaît la clé privée. N'importe quel service peut vérifier le token avec la clé publique exposée via le endpoint JWKS — sans risque.

// Dans le gateway — validation via JWKS public
.oauth2ResourceServer(oauth2 -> oauth2
    .jwt(jwt -> jwt
        .jwkSetUri("http://keycloak:8180/realms/bank/protocol/openid-connect/certs")
        .jwtAuthenticationConverter(jwtAuthConverter())
    )
)

// Converter pour extraire les rôles Keycloak
private Converter<Jwt, AbstractAuthenticationToken> jwtAuthConverter() {
    JwtGrantedAuthoritiesConverter converter = new JwtGrantedAuthoritiesConverter();
    converter.setAuthoritiesClaimName("realm_access.roles");
    converter.setAuthorityPrefix("ROLE_");
    return new ReactiveJwtAuthenticationConverterAdapter(
        new JwtAuthenticationConverter()
    );
}

RBAC avec les rôles Keycloak

Keycloak gère les rôles directement dans le realm. J'ai défini trois rôles : USER, ADMIN, et AUDITOR. Ces rôles sont inclus dans le JWT sous realm_access.roles. Spring Security les mappe automatiquement en authorities.

@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/api/accounts/all")
public Flux<Account> getAllAccounts() {
    return accountService.findAll();
}

@PreAuthorize("hasAnyRole('USER', 'ADMIN')")
@GetMapping("/api/accounts/{id}")
public Mono<Account> getAccount(@PathVariable String id, JwtAuthenticationToken auth) {
    // Vérification ownership : un USER ne peut voir que son compte
    return accountService.findByIdAndOwner(id, auth.getName());
}
Attention au claim realm_access vs resource_access dans Keycloak. Les rôles au niveau du realm sont dans realm_access.roles, les rôles spécifiques à un client sont dans resource_access.{client-id}.roles. Selon votre besoin, le converter est différent.

Ce que ça change en prod

  • Rotation des clés automatique via Keycloak — zéro intervention manuelle
  • Révocation de token via Keycloak Admin Console en un clic
  • Logs d'authentification centralisés dans Keycloak (qui s'est connecté, quand, depuis où)
  • Ajout d'un nouveau service : il suffit de déclarer un nouveau client dans Keycloak, sans toucher à l'auth
  • SSO natif : si demain j'ajoute un dashboard admin, il partage la même session Keycloak
Keycloak tourne dans le Docker Compose de prod sur le même réseau que les microservices. La configuration du realm est exportée en JSON et versionnée dans le repo infra — reproductible à 100% en cas de crash.
A
Achraf Ait M'Barek
Software Engineer · Java & Microservices

Ces articles reflètent mes choix d'architecture sur des projets réels. Les retours et axes d'amélioration sont les bienvenus.

// COMM_LINK_ONLINE

Disponible
immédiatement._

DISPO_IMMEDIATE
Bordeaux · France entière · Remote . Hybride .Présentiel
>[ Initier_Contact ]