Assurez la sécurité de votre application Spring en tirant parti des fonctionnalités robustes offertes par le framework Spring Security.

Le framework Spring Security sécurise votre application via l'authentification et l'autorisation. Dans son état par défaut, Spring Security garantit que chaque chemin de requête HTTP (ou page) dans votre application nécessite l'authentification d'un seul utilisateur global.

Ce cadre est également extrêmement flexible. Il vous permet de créer des règles de sécurité personnalisées pour chaque chemin de requête HTTP dans votre application, ainsi que pour les différents utilisateurs. Ainsi, vous pouvez supprimer la restriction de sécurité sur les pages qui ne nécessitent pas d'autorisation de l'utilisateur (comme une page d'accueil). Et définissez les rôles et les autorités de types d'utilisateurs spécifiques.

Ajouter Spring Security à votre application

Il existe deux façons d'ajouter Spring Security à votre application. Vous pouvez soit le sélectionner comme dépendance lors de la génération d'une nouvelle application Spring Boot

instagram viewer
en utilisant Spring initializr, ou ajoutez-le à votre fichier de spécification de construction dans la section dependency après avoir généré votre projet.

Si vous avez sélectionné l'une des options du projet Gradle, le fichier de dépendances est build.gradle. Cependant, si vous avez choisi Maven, ce fichier est pom.xml.

Ton build.gradle Le fichier doit contenir la dépendance suivante :

dependencies {
implementation 'org.springframework.boot: spring-boot-starter-security'
}

Alors que votre pom.xml Le fichier doit contenir la dépendance suivante :


org.springframework.boot
spring-boot-starter-security

L'exemple d'application utilisé dans l'article est disponible dans ce Référentiel GitHub et est libre d'utilisation sous la licence MIT.

Utilisation de Spring Security

Une fois que vous avez ajouté la dépendance Spring Security à votre application, vous pouvez commencer à utiliser le framework immédiatement. Exécutez simplement votre application, puis accédez à la page d'accueil de Spring Boot (ou à n'importe quelle page de votre application). L'exemple d'application utilise le contrôleur initial suivant pour contrôler la valeur par défaut de Spring Boot hôte local: 8080 demande:

package com.springSecurityDemo.controller;

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

@RestController
publicclassWebController{

@GetMapping("/")
public String home(){
return"Welcome!";
}
}

L'exécution de votre application après l'ajout de la classe de contrôleur unique ci-dessus génère la vue initiale suivante :

Vous remarquerez qu'il vous dirige automatiquement vers le hôte local: 8080/connexion page, et il le fait avant de vous permettre d'accéder à toute autre page de l'application. À ce stade, vous devrez fournir le nom d'utilisateur par défaut (qui est l'utilisateur) et le mot de passe généré automatiquement (que vous trouverez dans la console). La console générera une ligne comme celle-ci :

Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81

Chaque fois que vous redémarrez votre application, le mot de passe généré automatiquement changera, mais le nom d'utilisateur restera le même. La saisie du nom d'utilisateur et du mot de passe par défaut vous dirigera vers la vue appropriée dans votre application.

Personnalisation de la sécurité Spring

Pour personnaliser la sécurité de votre application, vous devrez remplacer la configuration par défaut de Spring Security. Mais avant cela (en supposant que vous ayez déjà Spring Web), vous aurez besoin de plusieurs autres dépendances pour cet exemple d'application :

  • JPA de données de printemps
  • Pilote MySQL JDBC
  • feuille de thym
  • Lombok

Le framework Thymeleaf générera différentes vues. Lombok vous aidera à réduire le code dans vos classes d'objets. La bibliothèque JPA et le pilote MySQL vous permettront d'utiliser une base de données MySQL avec l'application, mais vous avez la possibilité d'utiliser n'importe quelle base de données avec laquelle vous êtes à l'aise. Utiliser une base de données signifie configurer le applications.propriétés fichier sous le fichier des ressources.

spring.datasource.url=jdbc: mysql://${MYSQL_HOST: localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update

Le code de configuration ci-dessus vous permet de vous connecter à une base de données MySQL locale appelée spring_security, avec un nom d'utilisateur de racine, et mot de passe (1234). Vous devrez mettre à jour ces données pour qu'elles correspondent au nom et aux informations d'identification de votre base de données.

Après avoir ajouté vos dépendances supplémentaires et créé votre base de données, vous pouvez commencer à décider du nombre de vues de votre application. Vous devrez également savoir à quoi ressemble la sécurité de chaque page. Notre exemple d'application a 6 vues :

  • Page d'accueil
  • Page d'inscription
  • Page de connexion
  • Page de déconnexion
  • Page utilisateur
  • Page d'erreur

La seule vue qui nécessitera une autorisation de l'utilisateur est la page de l'utilisateur. Cette page n'est accessible qu'aux utilisateurs qui s'inscrivent d'abord, puis se connectent à l'application. En plus du package par défaut de Spring Boot, vous devrez créer quatre autres packages dans votre application.

La classe de contrôleur d'enregistrement

Le package du contrôleur contiendra les classes qui gèrent les requêtes HTTP. Selon la fonction d'une page, vous pouvez généralement regrouper chaque requête HTTP dans une classe de contrôleur, comme c'est le cas avec le WebController classe. Cependant, la vue d'enregistrement a des fonctions plus uniques, ainsi, elle peut avoir une classe de contrôleur privé :

@Controller
@RequestMapping("/register")
publicclassRegistrationController{
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;

publicRegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder){
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm(){
return"registration";
}
@PostMapping
public String processRegistration(RegistrationForm form){
userRepo.save(form.toUser(passwordEncoder));
return"redirect:/login";
}
}

Le Contrôleur d'enregistrement class est une passerelle vers l'aspect sécurité de votre application. Le @RequestMapping annotation spécifie le type de requête que ce contrôleur va gérer (requêtes à hôte local: 8080/s'inscrire).

Le @GetMapping l'annotation indique simplement que si l'application reçoit une demande de /register, le formulaire d'inscription() La méthode doit gérer cette demande en renvoyant la vue d'enregistrement.

Après qu'un visiteur a cliqué sur le bouton d'enregistrement, puis le @PostMapping l'annotation entre en jeu. Le processRegistration() La méthode vous permet de publier les données utilisateur qu'elle obtient de la Formulaire d'inscription classe à la base de données, à l'aide de la Référentiel utilisateur classe. Mais avant de stocker ces données, le processRegistration() chiffre le mot de passe de l'utilisateur à l'aide PrintempsCodeur de mot de passe interface.

Création de nouvelles configurations de sécurité

Depuis Spring 3.1, les développeurs peuvent désormais créer des configurations pour Spring Security à l'aide de Java, ce qui signifie des classes au lieu de XML. La principale chose que ces classes de configuration exigent est la @Configuration annotation.

@Configuration
publicclassSecurityConfiguration{
}

Le @Configuration L'annotation indique que la classe ci-dessus est une classe de configuration. Ces classes fournissent des haricots aux Contexte d'application du printemps, qui est un conteneur utilisé par Spring pour créer et gérer les différents composants (ou beans) d'une application. Le premier haricot du Configuration de la sécurité la classe est la passwordEncoder haricot.

@Bean
public PasswordEncoder passwordEncoder(){
 returnnew BCryptPasswordEncoder();
}

Le Contrôleur d'enregistrement classe utilise le passwordEncoder bean pour coder les nouveaux mots de passe avant de les enregistrer dans la base de données. Un autre haricot important que vous devrez ajouter au Configuration de la sécurité la classe est la userDetailsServiceuserDetailsService haricot.

@Bean
public UserDetailsService userDetailsService(UserRepository userRepo){
 return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
thrownew UsernameNotFoundException("Customer '" + username + "' not found");
 };
}

Le userDetailsServiceuserDetailsService le haricot emploie Sécurité du printempsUserDetailsService interface pour récupérer le nom d'utilisateur et le mot de passe d'un utilisateur pour l'authentification, lors de la session de connexion d'un client. Ainsi, dès qu'un client clique sur le bouton de connexion dans la vue de connexion, le userDetailsServiceuserDetailsService le haricot se met en mouvement.

À travers le Référentiel utilisateur, le userDetailsServiceuserDetailsService bean accède à tous les clients existants dans la base de données. Cette interface utilise alors le Référentiel utilisateur pour localiser un utilisateur avec un nom d'utilisateur et un mot de passe correspondants, puis renvoie tous les attributs de ce client sous forme d'objet.

Si l'objet renvoyé est un client, alors ce client accède à l'application. Sinon, la page sera automatiquement actualisée, permettant à l'utilisateur d'entrer des informations d'identification valides.

La chaîne de filtrage

Sécurité du printempsSecurityFilterChainSecurityFilterChain l'interface est utile interface de programmation d'applications (API) qui joue un rôle essentiel dans la configuration de Spring Security. Cette interface fonctionne avec Sécurité du printempsHttpSecurity class pour créer une chaîne de filtres pour des requêtes HTTP spécifiques.

@Bean
public SecurityFilterChain filterChain(HttpSecurity http)throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin -> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout -> logout.logoutSuccessUrl("/logout"));
 return http.build();
}

Le filtreChaîne haricot ci-dessus utilise le SecurityFilterChainSecurityFilterChain API pour accomplir plusieurs tâches. Tout d'abord, il utilise le HttpSecurity class pour dicter que seuls les utilisateurs ayant le rôle d'un USER peuvent accéder hôte local: 8080/utilisateur. Et un utilisateur obtient ce rôle après l'enregistrement, grâce à la getAuthorities() méthode que chaque nouvel objet client implémente.

@Override
public Collection extends="extends" grantedauthority="grantedauthority"?> getAuthorities() {
 return Arrays.asList(new SimpleGrantedAuthority("USER"));
}

La chaîne de filtrage permet un accès non authentifié à toutes les autres URL de l'application. Le filtreChaîne haricot utilise également le formLogin() et Se déconnecter() méthodes de la HttpSecurity objet de classe.

Ces méthodes vous permettent de diriger automatiquement un utilisateur vers des pages spécifiques après avoir effectué une tâche. Ainsi, un utilisateur qui entre les informations d'identification correctes et clique sur le bouton de connexion sur le /login la page sera automatiquement dirigée vers la /user page.

Finalement, le filtreChaîne bean construit et renvoie la chaîne de filtrage, qui permet aux utilisateurs autorisés d'accéder à l'application. Les trois haricots du Configuration de la sécurité classe travaillent ensemble pour sécuriser votre application.

Cependant, le filtreChaîne bean joue le rôle le plus important de dicter le niveau d'autorisation pour chaque requête HTTP. Lorsque vous commencez à ajouter d'autres pages à votre application, vous pouvez utiliser le filtreChaîne bean pour définir leur niveau de sécurité.

Le principal avantage de Spring Security

Spring Security vous donne un contrôle total non seulement sur qui a accès à votre application, mais également sur le type d'accès qu'un utilisateur peut avoir (via sa fonction de rôles d'utilisateur). Le contrôle d'accès est l'un des aspects les plus importants de toute application. Donner aux utilisateurs généraux un accès non filtré à votre application en raison de barrières de contrôle d'accès limitées peut s'avérer une erreur coûteuse.