11package com .moa .moa_server .config .security ;
22
3+ import lombok .RequiredArgsConstructor ;
4+ import org .springframework .beans .factory .annotation .Value ;
35import org .springframework .context .annotation .Bean ;
46import org .springframework .context .annotation .Configuration ;
57import org .springframework .context .annotation .Profile ;
6- import org .springframework .security . config . Customizer ;
8+ import org .springframework .http . HttpMethod ;
79import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
10+ import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
811import org .springframework .security .config .annotation .web .configurers .AbstractHttpConfigurer ;
12+ import org .springframework .security .config .http .SessionCreationPolicy ;
913import org .springframework .security .crypto .bcrypt .BCryptPasswordEncoder ;
1014import org .springframework .security .crypto .password .PasswordEncoder ;
1115import org .springframework .security .web .SecurityFilterChain ;
16+ import org .springframework .security .web .authentication .UsernamePasswordAuthenticationFilter ;
17+ import org .springframework .web .cors .CorsConfiguration ;
18+ import org .springframework .web .cors .CorsConfigurationSource ;
19+ import org .springframework .web .cors .UrlBasedCorsConfigurationSource ;
20+
21+ import java .util .List ;
1222
1323import static com .moa .moa_server .config .security .SecurityConstants .ALLOWED_URLS ;
1424
25+ @ RequiredArgsConstructor
26+ @ EnableWebSecurity
1527@ Configuration
1628@ Profile ("prod" )
1729public class ProdSecurityConfig {
1830
31+ @ Value ("${frontend.url}" )
32+ private String frontendUrl ;
33+
34+ private final JwtAuthenticationFilter jwtAuthenticationFilter ;
35+ private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint ;
36+
1937 @ Bean
20- public SecurityFilterChain securityFilterChain (HttpSecurity http ) throws Exception {
38+ public SecurityFilterChain securityFilterChain (HttpSecurity http , CorsConfigurationSource corsConfigurationSource ) throws Exception {
2139 http
22- .csrf (csrf -> {} )
23- .cors (Customizer . withDefaults ( ))
40+ .csrf (AbstractHttpConfigurer :: disable )
41+ .cors (cors -> cors . configurationSource ( corsConfigurationSource ))
2442 .httpBasic (AbstractHttpConfigurer ::disable )
2543 .formLogin (AbstractHttpConfigurer ::disable )
44+ .exceptionHandling (ex -> ex .authenticationEntryPoint (customAuthenticationEntryPoint ))
2645 .authorizeHttpRequests (auth -> auth
46+ .requestMatchers (HttpMethod .GET , "/api/v1/votes" ).permitAll ()
2747 .requestMatchers (ALLOWED_URLS ).permitAll ()
2848 .anyRequest ().authenticated ()
29- );
49+ )
50+ .sessionManagement (session -> session .sessionCreationPolicy (SessionCreationPolicy .STATELESS ))
51+ .addFilterBefore (jwtAuthenticationFilter , UsernamePasswordAuthenticationFilter .class );
3052
3153 return http .build ();
3254 }
3355
56+ /**
57+ * CORS 정책을 설정하고, 이를 Spring Security에 등록하는 Bean을 반환
58+ */
59+ @ Bean
60+ public CorsConfigurationSource corsConfigurationSource () {
61+ CorsConfiguration config = new CorsConfiguration ();
62+
63+ config .setAllowedOriginPatterns (List .of (frontendUrl )); // 요청을 허용할 출처(origin) 패턴을 설정
64+ config .setAllowedMethods (List .of ("GET" , "POST" , "PUT" , "DELETE" , "PATCH" , "OPTIONS" )); // 허용할 HTTP 메서드 목록 지정
65+ config .setAllowedHeaders (List .of ("*" )); // 모든 요청 헤더 허용
66+ config .setAllowCredentials (true ); // 인증 정보를 포함한 요청(Cookie 등)을 허용
67+
68+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource (); // 경로 별로 다른 CORS 설정을 적용할 수 있도록 지원하는 구현체
69+ source .registerCorsConfiguration ("/**" , config ); // 모든 경로에 위에서 설정한 CORS 정책을 적용
70+ return source ;
71+ }
72+
3473 @ Bean
3574 public PasswordEncoder passwordEncoder () { return new BCryptPasswordEncoder (); }
3675
37- }
76+ }
0 commit comments