JPA

Dans cet article, je voudrais partager comment se débarrasser de l’avertissement disant que « WebSecurityConfigurerAdapter is deprecated » dans une application basée sur Spring avec Spring Security.

Peut-être avez-vous l’habitude d’avoir une classe de configuration Spring qui étend la classe abstraite WebSecurityConfigurerAdapter comme ceci :

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
         
        // configurer la sécurité HTTP...
         
    }
 
    @Override
    public void configure(WebSecurity web) throws Exception {
         
        // configurer la sécurité Web...
         
    }      
}

Cela fonctionne bien avec Spring Security version 5.6.5 ou antérieure, ou avec Spring Boot version 2.6.8 ou antérieure. Cependant, si votre projet utilise Spring Security 5.7.1 ou plus récent, ou Spring Boot 2.7.0 ou plus récent, vous obtiendrez cet avertissement dans votre IDE :

Avertissement

Alors, pourquoi Spring Security déprécie-t-il l’utilisation de WebSecurityConfigurerAdapter ? et quelle est l’alternative ?

Eh bien, c’est parce que les développeurs du framework Spring encouragent les utilisateurs à s’orienter vers une configuration de la sécurité basée sur les composants.

Ainsi, au lieu d’étendre WebSecurityConfigurerAdapter et de surcharger les méthodes de configuration de HttpSecurity et WebSecurity comme dans l’ancienne méthode, vous devez maintenant déclarer deux beans de type SecurityFilterChain et WebSecurityCustomizer comme suit :

@Configuration
public class SecurityConfiguration {
         
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     
    }
     
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
         
    }
}

Voici un exemple de code de migration de la configuration de la sécurité vers une approche basée sur les composants. Tout d’abord, examinons une classe de configuration de sécurité typique avec WebSecurityConfigurerAdapter comme indiqué ci-dessous :

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Bean
    public UserDetailsService userDetailsService() {
        return new MyUserDetailsService();
    }
 
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
     
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/login").permitAll()
                .antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
                .hasAnyAuthority("Admin", "Editor")
                .anyRequest().authenticated()
                .and().formLogin()
                .loginPage("/login")
                    .usernameParameter("email")
                    .permitAll()
                .and()
                .rememberMe().key("GFjhirnjFGhtjvKOPjth_956823561")
                .and()
                .logout().permitAll();
 
        http.headers().frameOptions().sameOrigin();
    }
     
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**"); 
    }
}

Et voici une alternative, sans WebSecurityConfigurerAdapter :

package net.autourducode;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
 
@Configuration
public class SecurityConfiguration {
 
    @Bean
    public UserDetailsService userDetailsService() {
        return new MyUserDetailsService();
    }
 
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     
        http.authorizeRequests().antMatchers("/login").permitAll()
                .antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
                .hasAnyAuthority("Admin", "Editor")
                .anyRequest().authenticated()
                .and().formLogin()
                .loginPage("/login")
                    .usernameParameter("email")
                    .permitAll()
                .and()
                .rememberMe().key("GFjhirnjFGhtjvKOPjth_956823561")
                .and()
                .logout().permitAll();
 
        http.headers().frameOptions().sameOrigin();
 
        return http.build();
    }
 
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");
    }
 
}

Déclare un bean de type AuthenticationProvider : 

Dans le cas où vous avez besoin d’exposer un bean de type AuthenticationManager, vous pouvez mettre le code suivant :

@Bean
public AuthenticationManager authenticationManager(
        AuthenticationConfiguration authConfig) throws Exception {
    return authConfig.getAuthenticationManager();
}

Déclarer un bean de type AuthenticationProvider :

Si vous devez exposer un bean de type AuthenticationProvider, tel que DaoAuthenticationProvider, utilisez le code suivant :

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
     
    authProvider.setUserDetailsService(userDetailsService());
    authProvider.setPasswordEncoder(passwordEncoder());
 
    return authProvider;
}

et spécifier ce fournisseur d’authentification pour HttpSecurity dans le code de SecurityFilterChain comme suit :

http.authenticationProvider(authenticationProvider());

Voici comment supprimer l’avertissement « WebSecurityConfigurerAdapter is deprecated » dans une application basée sur Spring avec Spring Security. Vous devez déclarer les beans SecurityFilterChain et WebSecurityCustomizer au lieu de surcharger les méthodes de la classe WebSecurityConfigurerAdapter.

REMARQUE : Si vous ne souhaitez pas modifier votre code actuel, vous devez conserver une version de Spring Boot inférieure à 2.7.0 ou une version de Spring Security antérieure à 5.7.1.

J’espère que cet article vous a été utile. Merci de l’avoir lu.
Référence : Spring Security without the WebSecurityConfigurerAdapter

Retrouvez nos vidéos #autourducode sur notre chaîne YouTube : https://bit.ly/3IwIK04