• 8 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 16/11/2023

Configurez une page de connexion personnalisée avec Spring Security

Commençons par configurer la chaîne de filtres de sécurité de Spring Security pour l’authentification et l’autorisation.

Suivez moi dans la démonstration suivante :

Démarrez par le formulaire Spring Security par défaut, en utilisant la méthode  formLogin(Customizer.withDefaults())  .

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	return http.formLogin(Customizer.withDefaults()).build();
}

Ajoutez des rôles d’utilisateur et d'administrateur à votre chaîne de filtres

Spring Security fournit des filtres qui peuvent être utilisés pour authentifier différents types de rôles. Définissez les deux rôles suivants dans votre application Spring Boot :

  1. Utilisateur.

  2. Administrateur.

Une fois qu'ils sont authentifiés, Spring Security se charge d’octroyer les autorisations appropriées, et contrôle l’accès aux données selon les rôles.

En premier lieu, ajoutez la méthode  authorizeHttpRequests()  pour définir les rôles.

Ensuite, ajoutez la méthode   requestMatchers()  pour définir l'association des rôles  USER  (utilisateur) et ADMIN  (administrateur) avec des pages.

Cela permettra d’assurer l’étape d'autorisation pour les pages qui sont à la disposition des utilisateurs. Le rôle  ADMIN  se voit attribuer une page d’accueil spécifique,  /admin  , mais a également accès à  /user  . Les utilisateurs ont accès à la page d’accueil  /user  , mais ne devraient pas avoir accès à la page d’accueil  /admin  . Ajoutez  anyRequest().authenticated()  pour vous permettre d’utiliser le formulaire ci-dessous pour l’authentification.

Procédez comme suit, en ajoutant l’extrait de code à votre méthode   filterChain()  qui gère les requêtes HTTP.

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	return http.authorizeHttpRequests(auth -> {
		auth.requestMatchers("/admin").hasRole("ADMIN");
		auth.requestMatchers("/user").hasRole("USER");
		auth.anyRequest().authenticated();
	}).formLogin(Customizer.withDefaults()).build();
}

Votre chaîne de filtres de sécurité est programmée avec HTTPSecurity.

Maintenant, nous pouvons créer une chaîne de filtres de sécurité pour l'étape d’authentification de ce petit chef-d'œuvre.

Ajoutez des utilisateurs en mémoire

Sans utilisateur, notre chaîne de filtres de sécurité ne nous permettra pas d’aller bien loin. Pour commencer voyons comment ajouter des utilisateurs avec des rôles.

Ces utilisateurs seront définis en mémoire, bien que dans des projets de production cette méthode est à proscrire au bénéfice d’utilisateurs stockées par exemple dans une base de données.

Il faut ajouter une nouvelle méthode qui renverra une implémentation de l’interface UserDetailsService. Dans le monde de Spring Security, l’objet UserDetails permet de modéliser un utilisateur. L’objet UserDetailsService permet d’accéder à des utilisateurs.

@Bean
public UserDetailsService users() {
	UserDetails user = User.builder()
			.username("user")
			.password(passwordEncoder().encode("user"))
			.roles("USER").build();
	UserDetails admin = User.builder()
			.username("admin")
			.password(passwordEncoder().encode("admin"))
			.roles("USER", "ADMIN").build();
	return new InMemoryUserDetailsManager(user, admin);
}
	
@Bean
public BCryptPasswordEncoder passwordEncoder() {
	return new BCryptPasswordEncoder();
}

Je vous ai préparé un utilisateur et un admin avec lesquels vous pouvez vous connecter. Voici les identifiants :

  • USER role : utilisateur : user ; mot de passe : user.

  • ADMIN role : utilisateur : admin ; mot de passe : admin.

J’ai également ajouté un encodage aux mots de passe. Ainsi, même si j’ai écrit en dur des mots de passe simples, la méthode   encode()  permet comme son nom l’indique de les encoder.

Pour mener à bien cet encodage, la méthode passwordEncoder() a été rajoutée. Elle renvoie une instance de BCryptEncoder.

BCrypt est l’un des algorithmes d’encodage les plus reconnus en ce qui concerne les mots de passe. Je vous le recommande.

Révisez votre chaîne de filtres de sécurité

Révisons le fichier SpringSecurityconfig.java que vous venez de compléter. Il devrait ressembler à ça :

package com.openclassrooms.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {
	
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		return http.authorizeHttpRequests(auth -> {
			auth.requestMatchers("/admin").hasRole("ADMIN");
			auth.requestMatchers("/user").hasRole("USER");
			auth.anyRequest().authenticated();
		}).formLogin(Customizer.withDefaults()).build();
	}
	
	@Bean
	public UserDetailsService users() {
		UserDetails user = User.builder()
				.username("user")
				.password(passwordEncoder().encode("user"))
				.roles("USER").build();
		UserDetails admin = User.builder()
				.username("admin")
				.password(passwordEncoder().encode("admin"))
				.roles("USER", "ADMIN").build();
		return new InMemoryUserDetailsManager(user, admin);
	}
	
	@Bean
	public BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	

}

Mettez en place votre Contrôleur

Maintenant, il est temps de mettre en place votre contrôleur. Ce contrôleur va gérer l’affichage des pages une fois que nous serons authentifiés.

Nous allons créer deux pages :

  • une pour l’utilisateur ;

  • et une autre pour l’administrateur.

Dans cette démonstration nous avons suivi les étapes suivantes :

  • Faites un clic droit sur votre package com.openclassrooms -> New -> Package.

  • Pour le nom du package, ajoutez le mot controllers à votre nom de package principal. Le mien s’intitule com.openclassrooms.controllers.

  • Puis, faites un clic droit sur le package que vous venez de réaliser, com.openclassrooms.controller -> New -> Class.

  • Intitulez votre classe contrôleur LoginController.java.

  • Ajoutez l’annotation  @RestController  pour la prise en compte de votre classe en tant que contrôleur REST par Spring. 

Ensuite, créez une méthode différente pour chaque rôle et utilisez l’annotation @GetMapping pour associer l’URL.

package com.openclassrooms.controllers;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {

	@GetMapping("/user")
	public String getUser() {
		return "Welcome, User";
	}
	
	@GetMapping("/admin")
	public String getAdmin() {
		return "Welcome, Admin";
	}
	
}

Maintenant, voyons ce que ça donne dans le navigateur.

Mettez en place votre Serveur Web

Lorsque vous lancez votre application, un serveur web Tomcat est démarré. Aucune configuration n’est nécessaire ; tout s’effectue automatiquement à la compilation et à l'exécution du code.

Plusieurs façons permettent de démarrer l’application. Dans mon cas, j’utilise le goal Maven : spring-boot:run

Une fois le démarrage complété, vous pouvez ouvrir votre application web sur votre navigateur.

Maintenant, connectez-vous en tant que user et voyez ce qu’il se passe.

Le formulaire de connexion de Spring Security par défaut. On peut y entrer un identifiant de connexion et un mot de passe puis cliquer sur le bouton pour se connecter.
Le formulaire de connexion de Spring Security par défaut

Yes, ça fonctionne ! Déconnectez vous avec la page http://localhost:8080/logout puis essayez l’utilisateur “admin”.

Voici quelques tests à mener pour être certain que vous l’avez correctement mis en place :

  • Que se passe-t-il lorsque vous rentrez le mauvais mot de passe ? 

  • Que se passe-t-il lorsque vous tentez de consulter la page /admin alors que vous êtes connecté en tant que user ?  

En résumé

Vous avez fait du beau travail, vous savez maintenant :

  • Créer des filtres avec authorizeHttpRequests()  et requestMatchers() pour appliquer le contrôle d’accès basé sur des rôles à différentes URL. 

  • Configurer le rôle des utilisateurs en utilisant une implémentation de UserDetailsService

  • Mettre en place les méthodes permettant de créer des pages d'accueil dynamiques pour les utilisateurs, en ayant recours à l’annotation GetMapping .

On dirait que votre page d’authentification Spring Security est prête.

Dans le prochain chapitre apprenez à configurez une authentification basée sur des utilisateurs en base de données.

Exemple de certificat de réussite
Exemple de certificat de réussite