Sécurisation de Java EE avec Spring Security

Sécurisation de Java EE avec Spring Security

1. Vue d'ensemble

Dans ce rapide didacticiel, nous allons voir commentsecure a Java EE web application with Spring Security.

2. Dépendances Maven

Commençons par lesSpring Security dependencies requis pour ce tutoriel:


    org.springframework.security
    spring-security-web
    4.2.3.RELEASE


    org.springframework.security
    spring-security-config
    4.2.3.RELEASE


    org.springframework.security
    spring-security-taglibs
    4.2.3.RELEASE

La dernière version de Spring Security (au moment de la rédaction de ce tutoriel) est 4.2.3.RELEASE; comme toujours, nous pouvons vérifierMaven Central pour les dernières versions.

3. Configuration de sécurité

Ensuite, nous devons configurer la configuration de la sécurité pour l’application Java EE existante:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig
  extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1").password("user1Pass").roles("USER")
          .and()
          .withUser("admin").password("adminPass").roles("ADMIN");
    }
}

Dans la méthodeconfigure(), nous configurons lesAuthenticationManager. Par souci de simplicité, nous implémentons une authentification simple en mémoire. Les détails de l'utilisateur sont codés en dur.

Ceci est destiné à être utilisé pour le prototypage rapide lorsqu'un mécanisme de persistance complet n'est pas nécessaire.

Ensuite, intégrons la sécurité dans le système existant en ajoutant la classeSecurityWebApplicationInitializer:

public class SecurityWebApplicationInitializer
  extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(SpringSecurityConfig.class);
    }
}

Cette classe garantira que leSpringSecurityConfig est chargé lors du démarrage de l'application. À ce stade,we’ve achieved a basic implementation of Spring Security. Avec cette implémentation, Spring Security nécessitera une authentification pour toutes les demandes et tous les itinéraires par défaut.

4. Configuration des règles de sécurité

Nous pouvons personnaliser davantage Spring Security en remplaçant la méthodeWebSecurityConfigurerAdapter deconfigure(HttpSecurity http):

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .authorizeRequests()
      .antMatchers("/auth/login*").anonymous()
      .anyRequest().authenticated()
      .and()
      .formLogin()
      .loginPage("/auth/login")
      .defaultSuccessUrl("/home", true)
      .failureUrl("/auth/login?error=true")
      .and()
      .logout().logoutSuccessUrl("/auth/login");
}

En utilisant la méthodeantMatchers(), nous configurons Spring Security pour autoriser l'accès anonyme à/auth/login et __ authentifier toute autre requête.

4.1. Page de connexion personnalisée

Une page de connexion personnalisée est configurée à l'aide de la méthodeformLogin():

http.formLogin()
  .loginPage("/auth/login")

Si ce n'est pas spécifié, Spring Security génère une page de connexion par défaut à/login:




Login

User:
Password:

4.2. Page de destination personnalisée

Une fois la connexion réussie, Spring Security redirige l'utilisateur vers la racine de l'application. Nous pouvons remplacer cela en spécifiant une URL de succès par défaut:

http.formLogin()
  .defaultSuccessUrl("/home", true)

En définissant le paramètrealwaysUse de la méthodedefaultSuccessUrl() sur true, un utilisateur sera toujours redirigé vers la page spécifiée.

Si le paramètrealwaysUse n'est pas défini ou est défini sur false, un utilisateur sera redirigé vers la page précédente à laquelle il a tenté d'accéder avant d'être invité à s'authentifier.

De même, nous pouvons également spécifier une page de destination d'échec personnalisé:

http.formLogin()
  .failureUrl("/auth/login?error=true")

4.3. Autorisation

Nous pouvons limiter l'accès à une ressource par rôle:

http.formLogin()
  .antMatchers("/home/admin*").hasRole("ADMIN")

Un utilisateur non-administrateur recevra une erreur d'accès refusé s'il essaie d'accéder au point de terminaison/home/admin.

Nous pouvons également restreindre les données d'une page JSP en fonction du rôle d'un utilisateur. Ceci est fait en utilisant la balise<security:authorize>:


    This text is only visible to an admin
    
">Admin Page

Pour utiliser cette balise, nous devons inclure la balise balise Spring Security en haut de la page:

<%@ taglib prefix="security"
  uri="http://www.springframework.org/security/tags" %>

5. Configuration XML de sécurité Spring

Jusqu'à présent, nous avons examiné la configuration de Spring Security en Java. Jetons un œil à une configuration XML équivalente.

Tout d'abord, nous devons créer un fichiersecurity.xml dans le dossierweb/WEB-INF/spring qui contient nos configurations XML. Un exemple d'un tel fichier de configurationsecurity.xml est disponible à la fin de l'article.

Commençons par configurer le gestionnaire d’authentification et le fournisseur d’authentification. Par souci de simplicité, nous utilisons des informations d'identification d'utilisateur codées en dur:


    
        
            
        
    

Ce que nous venons de faire est de créer un utilisateur avec un nom d'utilisateur, un mot de passe et un rôle.

Alternativement, nous pouvons configurer notre fournisseur d'authentification avec un encodeur de mot de passe:


    
        
        
            
        
    

Nous pouvons également spécifier une implémentation personnalisée de Spring'sUserDetailsService ou aDatasource en tant que fournisseur d'authentification. Plus de détails peuvent être trouvéshere.

Maintenant que nous avons configuré le gestionnaire d'authentification, configurons les règles de sécurité et appliquons le contrôle d'accès:


    
    
    
    

Dans l'extrait de code ci-dessus, nous avons configuréHttpSecurity pour utiliser la connexion par formulaire et avons défini/secure.jsp comme URL de réussite de la connexion. Nous avons accordé un accès anonyme à/index.jsp et au chemin“/”. De plus, nous avons spécifié que l'accès à/secure.jsp devrait nécessiter une authentification et qu'un utilisateur authentifié devrait avoir, au moins, le niveau d'autoritéROLE_USER.

La définition de l'attributauto-config de la balisehttp surtrue indique à Spring Security d'implémenter des comportements par défaut que nous n'avons pas à remplacer dans la configuration. Par conséquent,/login et/logout seront utilisés respectivement pour la connexion et la déconnexion de l'utilisateur. Une page de connexion par défaut est également fournie.

Nous pouvons personnaliser davantage la baliseform-login avec des pages de connexion et de déconnexion personnalisées, des URL pour gérer à la fois l'échec et le succès de l'authentification. LeSecurity Namespace appendix liste tous les attributs possibles pour les balisesform-login (et autres). Certains IDE rendent également possible l'inspection en cliquant sur une étiquette tout en appuyant sur la touchectrl.

Enfin, pour que la configuration desecurity.xml soit chargée lors du démarrage de l'application, nous devons ajouter les définitions suivantes à nosweb.xml:


    contextConfigLocation
    
      /WEB-INF/spring/*.xml
    



    springSecurityFilterChain
    
      org.springframework.web.filter.DelegatingFilterProxy



    springSecurityFilterChain
    /*



    
        org.springframework.web.context.ContextLoaderListener
    

Notez que l'utilisation de configurations à la fois XML et Java dans la même application JEE peut provoquer des erreurs.

6. Conclusion

Dans cet article, nous avons vu comment sécuriser une application Java EE avec Spring Security et présenté des configurations à la fois en Java et en XML.

Nous avons également discuté des moyens d'accorder ou de révoquer l'accès à des ressources spécifiques en fonction du rôle d'un utilisateur.

Le code source complet et les définitions XML sont disponiblesover on GitHub.