Spring · Fiche 05

Spring Security

Framework de sécurité pour les applications Spring : authentification, autorisation et configuration de la SecurityFilterChain.

Spring Security est le framework de sécurité des applications Spring : il prend en charge l’authentification et l’autorisation via une chaîne de filtres configurables.

🔐 Concepts clés

Authentification

Vérification de l’identité : qui est l’utilisateur ?

  • Form-based, HTTP Basic, JWT
  • OAuth2, LDAP, Database

Autorisation

Contrôle d’accès aux ressources : que peut faire cet utilisateur ?

  • Rôles et permissions
  • Method-level security

Piège d’entretien : ne pas confondre les deux — l’authentification établit QUI vous êtes (login), l’autorisation détermine ce que vous avez le DROIT de faire (accès aux ressources). L’authentification précède toujours l’autorisation.

⚙️ Configuration de base

La configuration moderne (Spring Security 6) passe par un bean SecurityFilterChain et le DSL lambda de HttpSecurity.

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    private final UserDetailsService userDetailsService;
    private final PasswordEncoder passwordEncoder;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(session ->
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/api/auth/**").permitAll()
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers(HttpMethod.GET, "/api/products/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .requestMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .formLogin(form -> form
                .loginPage("/login")
                .defaultSuccessUrl("/dashboard")
                .failureUrl("/login?error=true")
                .permitAll()
            )
            .logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout=true")
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
            );

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

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

// Service UserDetails personnalisé
@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByEmail(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));

        return org.springframework.security.core.userdetails.User.builder()
            .username(user.getEmail())
            .password(user.getPassword())
            .authorities(getAuthorities(user.getRoles()))
            .accountExpired(false)
            .accountLocked(false)
            .credentialsExpired(false)
            .disabled(!user.isEnabled())
            .build();
    }

    private Collection<? extends GrantedAuthority> getAuthorities(Set<Role> roles) {
        return roles.stream()
            .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName()))
            .collect(Collectors.toList());
    }
}

Interro écrite

8 questions pour valider la fiche. Une seule réponse par question.

Question 1/8Quelle est la différence entre authentification et autorisation ?