Aller au contenu

Keycloak avec Spring Boot-Thymeleaf

Le cheminement est un peu différent d’un JWT fait maison. Dans un schéma classique JWT, c’est votre application Spring Boot qui reçoit le login/mot de passe, vérifie l’utilisateur, puis génère le JWT. Avec Keycloak, ce n’est plus votre application qui gère directement le login/mot de passe. C’est Keycloak qui devient le serveur d’authentification.


1. Version JWT classique

Votre schéma :

1. L’utilisateur envoie son login et mot de passe
2. Le serveur vérifie que les 2 sont ok
3. Le serveur génère un JWT
4. Le client envoie le JWT dans les requêtes suivantes
5. Le serveur valide le token

Dans ce cas :

Navigateur → Application Spring Boot

L’application Spring Boot fait tout :

authentification
vérification du mot de passe
génération du token
validation du token
gestion des rôles

2. Keycloak + Spring Boot + Thymeleaf

Avec Keycloak, le cheminement devient :

1. L’utilisateur demande une page protégée dans Spring Boot
2. Spring Boot redirige l’utilisateur vers Keycloak
3. L’utilisateur saisit son login et mot de passe dans Keycloak
4. Keycloak vérifie le login et le mot de passe
5. Keycloak renvoie l’utilisateur vers Spring Boot avec un code d’autorisation
6. Spring Boot échange ce code contre des tokens auprès de Keycloak
7. Spring Boot crée une session web pour l’utilisateur
8. L’utilisateur navigue dans l’application Thymeleaf avec un cookie de session
9. Spring Security utilise les informations Keycloak pour connaître l’utilisateur et ses rôles

3. Comparaison étape par étape

JWT classique Keycloak + Spring Boot + Thymeleaf
L’utilisateur envoie login/mot de passe à Spring Boot L’utilisateur est redirigé vers Keycloak
Spring Boot vérifie le mot de passe Keycloak vérifie le mot de passe
Spring Boot génère le JWT Keycloak génère les tokens
Le navigateur stocke et renvoie le JWT Le navigateur utilise surtout une session Spring Boot
Spring Boot valide le JWT à chaque requête API Spring Security gère la session et les droits
Spring Boot contient la logique d’authentification Keycloak centralise l’authentification

4. Cheminement concret avec Thymeleaf

Supposons une application Spring Boot avec ces pages :

/
page publique

/chiens
page protégée

/admin
page réservée aux administrateurs

Étape 1 — L’utilisateur demande une page protégée

L’utilisateur va sur :

GET http://localhost:8080/chiens

Spring Security voit que la page est protégée, il redirige vers Keycloak :

http://localhost:8081/realms/wouafwouaf/protocol/openid-connect/auth...

Étape 2 — Keycloak affiche la page de connexion

L’utilisateur ne saisit pas son mot de passe dans votre application Thymeleaf. Il le saisit dans Keycloak :

Login : philippe
Mot de passe : ****

Étape 3 — Keycloak vérifie l’utilisateur

Keycloak vérifie :

utilisateur existe-t-il ?
mot de passe est-il correct ?
compte est-il actif ?
rôle est-il attribué ?

Si tout est correct, Keycloak ne donne pas directement la page /chiens.

Il redirige vers Spring Boot avec un code d’autorisation.


Étape 4 — Spring Boot récupère les tokens

Spring Boot reçoit un code, puis contacte Keycloak en arrière-plan. Keycloak renvoie notamment :

access_token
id_token
refresh_token

L’access_token est souvent un JWT. Mais dans une application Thymeleaf, ce token n’est généralement pas manipulé directement par vos templates.

Spring Security l’utilise pour établir l’authentification.


Étape 5 — Spring Boot crée une session

Pour une application web classique Thymeleaf, Spring Boot fonctionne souvent avec une session HTTP. Le navigateur reçoit un cookie :

JSESSIONID=...

Ensuite, à chaque page demandée :

GET /chiens
Cookie: JSESSIONID=...

Le navigateur n’a pas besoin d’envoyer manuellement :

Authorization: Bearer eyJhbGciOi...

C’est une différence importante avec une API REST pure.


5. Schéma simple

Navigateur
   |
   | 1. Demande /chiens
   v
Spring Boot + Thymeleaf
   |
   | 2. Redirection login
   v
Keycloak
   |
   | 3. Login / mot de passe
   | 4. Authentification OK
   v
Spring Boot
   |
   | 5. Récupère les tokens
   | 6. Crée une session
   v
Navigateur
   |
   | 7. Navigue avec JSESSIONID
   v
Pages Thymeleaf protégées

6. Donc, utilise-t-on encore un JWT ?

Oui, mais pas de la même manière.

Avec Thymeleaf :

Keycloak génère bien des tokens, dont souvent un JWT.
Spring Boot les reçoit et les utilise.
Mais le navigateur navigue ensuite surtout avec un cookie de session.

Avec une API REST pure :

Le front-end envoie souvent directement le JWT dans l’en-tête Authorization vers le back-end

Donc :

Application Thymeleaf = logique session web
Application API REST = logique Bearer Token

7. Exemple avec Spring Security

Dans une application Thymeleaf, on configure plutôt Spring Boot comme OAuth2 Client.

Exemple simplifié :

spring:
  security:
    oauth2:
      client:
        registration:
          keycloak:
            client-id: wouafwouaf-thymeleaf
            client-secret: secret
            scope: openid, profile, email
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"

        provider:
          keycloak:
            issuer-uri: http://localhost:8081/realms/wouafwouaf

Ici, Spring Boot dit :

Je délègue la connexion à Keycloak.

8. Configuration SecurityFilterChain simple

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/", "/css/**", "/js/**").permitAll()
                        .requestMatchers("/admin/**").hasRole("ADMIN")
                        .anyRequest().authenticated()
                )
                .oauth2Login(oauth2 -> oauth2
                        .defaultSuccessUrl("/chiens", true)
                )
                .logout(logout -> logout
                        .logoutSuccessUrl("/")
                )
                .build();
    }
}

Avec cette configuration :

/               accessible sans connexion
/css/**         accessible sans connexion
/admin/**       réservé au rôle ADMIN
autres pages    utilisateur connecté obligatoire

9. Différence entre OAuth2 Client et Resource Server

Application Thymeleaf

Pour Thymeleaf, on utilise généralement :

spring-boot-starter-oauth2-client

Pourquoi ?

Parce que l’application web redirige l’utilisateur vers Keycloak, récupère les tokens, puis gère une session.

Spring Boot = OAuth2 Client

API REST

Pour une API REST, on utilise généralement :

spring-boot-starter-oauth2-resource-server

Pourquoi ?

Parce que l’API reçoit des requêtes avec :

Authorization: Bearer eyJhbGciOi...

Et elle doit vérifier le JWT.

Spring Boot = Resource Server

10. Résumé

JWT classique

Navigateur → Spring Boot
login/mot de passe → Spring Boot
Spring Boot génère le JWT
Navigateur renvoie le JWT
Spring Boot valide le JWT

Keycloak + Thymeleaf

Navigateur → Spring Boot
Spring Boot redirige vers Keycloak
Keycloak vérifie login/mot de passe
Keycloak renvoie vers Spring Boot
Spring Boot récupère les tokens
Spring Boot crée une session
Navigateur navigue avec JSESSIONID

11. Formule à retenir

Avec Keycloak :

Votre application ne vérifie plus le mot de passe.
Votre application fait confiance à Keycloak.

Avec Thymeleaf :

Le JWT existe côté sécurité, mais l’utilisateur navigue surtout avec une session web.

Avec une API REST :

Le JWT est envoyé explicitement dans chaque requête HTTP.

Donc, avec Spring Boot + Thymeleaf, le cheminement équivalent est :

1. L’utilisateur demande une page protégée
2. Spring Boot redirige vers Keycloak
3. Keycloak récupère login/mot de passe
4. Keycloak authentifie l’utilisateur
5. Keycloak renvoie vers Spring Boot
6. Spring Boot récupère et valide les tokens
7. Spring Boot crée une session utilisateur
8. Thymeleaf affiche les pages selon les rôles