package com.example.backend.config; import com.example.backend.services.UserService; import com.nimbusds.jose.jwk.JWK; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.ImmutableJWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; 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.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtEncoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; @Configuration @EnableWebSecurity public class SecurityConfig { public static final String[] PUBLIC_URL_PATTERNS = { "/registrations/**", "/login", "/home", "/auth/**", "/event", "/events/**", "/api/events/**", "/api/registrations/**", "/api/forum/**", "/forum/**", "/replies/**", "/replies/forum/**", "/error", "/forum/replies/{id}", "/api/api-docs", "/api/swagger-ui/**", "/api/swagger-ui.html" }; private final JWTFilter filter; private final UserService userService; @Autowired public SecurityConfig(JWTFilter filter, UserService userService) { this.filter = filter; this.userService = userService; } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .csrf(AbstractHttpConfigurer::disable) .cors(Customizer.withDefaults()) .httpBasic(Customizer.withDefaults()) .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .userDetailsService(userService) .addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests((auth) -> auth .requestMatchers(PUBLIC_URL_PATTERNS).permitAll() .requestMatchers("/error").anonymous() .requestMatchers("/ideas/**").permitAll() .anyRequest().authenticated() ) .build(); } @Value("${jwt.public.key}") private RSAPublicKey key; @Value("${jwt.private.key}") private RSAPrivateKey priv; @Bean public JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withPublicKey(this.key).build(); } @Bean public JwtEncoder jwtEncoder() { final JWK jwk = new RSAKey.Builder(this.key).privateKey(this.priv).build(); final JWKSource jwks = new ImmutableJWKSet<>(new JWKSet(jwk)); return new NimbusJwtEncoder(jwks); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } }