package app.mealsmadeeasy.api.security; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import java.util.List; @Configuration @EnableWebSecurity @EnableMethodSecurity public class SecurityConfiguration { private final JpaUserDetailsService jpaUserDetailsService; private final BeanFactory beanFactory; private final List endpointAuthConfigurators; public SecurityConfiguration( JpaUserDetailsService jpaUserDetailsService, BeanFactory beanFactory, List endpointAuthConfigurators ) { this.jpaUserDetailsService = jpaUserDetailsService; this.beanFactory = beanFactory; this.endpointAuthConfigurators = endpointAuthConfigurators; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeHttpRequests(requests -> { this.endpointAuthConfigurators.forEach(endpointAuthConfigurator -> { endpointAuthConfigurator.configure(requests); }); }); httpSecurity.csrf(AbstractHttpConfigurer::disable); httpSecurity.cors(Customizer.withDefaults()); httpSecurity.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy( SessionCreationPolicy.STATELESS )); httpSecurity.exceptionHandling(exceptionHandling -> { exceptionHandling.authenticationEntryPoint((request, response, authException) -> { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); }); }); httpSecurity.addFilterBefore( this.beanFactory.getBean(JwtFilter.class), UsernamePasswordAuthenticationFilter.class ); return httpSecurity.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(10); } @Bean public DaoAuthenticationProvider daoAuthenticationProvider() { final var provider = new DaoAuthenticationProvider(this.jpaUserDetailsService); provider.setPasswordEncoder(this.beanFactory.getBean(PasswordEncoder.class)); return provider; } @Bean public AuthenticationManager authenticationManager() { return new ProviderManager(this.beanFactory.getBean(AuthenticationProvider.class)); } }