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.
/8