package com.example.app.configurations; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.example.app.filters.JwtAuthFilter; import lombok.RequiredArgsConstructor; @Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfiguration { private final JwtAuthFilter jwtAuthFilter; private final UserDetailsService userDetailsService; private final PasswordEncoder passwordEncoder; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // Disable CSRF (not needed for stateless JWT) .csrf(csrf -> csrf.disable()) // Configure endpoint authorization .authorizeHttpRequests(auth -> auth .requestMatchers("/users/auth", "/users", "/docs/**", "/v3/api-docs") .permitAll() .requestMatchers("/auth/user/**").hasAuthority("ROLE_USER") .requestMatchers("/auth/admin/**").hasAuthority("ROLE_ADMIN") .anyRequest().authenticated()) // Stateless session (required for JWT) .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // Add JWT filter before Spring Security's default filter .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } /* * Authentication manager bean * Required for programmatic authentication (e.g., in /generateToken) */ @Bean public AuthenticationManager authenticationManager() throws Exception { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(userDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(authenticationProvider); } }