From 9b52aa0daf798e9f7c6e8a2bc689336cfa8c194a Mon Sep 17 00:00:00 2001 From: larama-C Date: Mon, 15 Dec 2025 14:05:20 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20Spring=20Security=20CORS,=20?= =?UTF-8?q?=EC=9D=B8=EA=B0=80=20=EA=B7=9C=EC=B9=99=20=EB=B0=8F=20Stateless?= =?UTF-8?q?=20=EC=84=B8=EC=85=98=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/security/SecurityConfig.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/security/SecurityConfig.java b/src/main/java/com/back/web7_9_codecrete_be/global/security/SecurityConfig.java index b88226c8..971f0e1a 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/security/SecurityConfig.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/security/SecurityConfig.java @@ -8,8 +8,13 @@ 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.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.List; @Configuration @RequiredArgsConstructor @@ -36,6 +41,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti // H2 Console 설정 .headers(headers -> headers.frameOptions(frame -> frame.disable())) + // 세션 관리 설정 - Stateless + .sessionManagement((session) -> session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + // Authorization 설정 .authorizeHttpRequests(auth -> auth .requestMatchers( @@ -45,6 +54,13 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti "/h2-console/**", // H2 Console "/api/v1/concerts/**" // concert 정보 조회 도메인 ).permitAll() + + // ADMIN 전용 + .requestMatchers("/api/v1/admin/**").hasRole("ADMIN") + + // USER, ADMIN 허용 + .requestMatchers("/api/v1/users/**").hasAnyRole("USER", "ADMIN") + .anyRequest().authenticated() ) @@ -60,4 +76,23 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { return configuration.getAuthenticationManager(); } + + // CORS 설정(로컬 프론트 통신 허용) + @Bean + public UrlBasedCorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration =new CorsConfiguration(); + + configuration.setAllowedOrigins(List.of("http://localhost:3000")); + configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")); + + configuration.setAllowedHeaders(List.of("*")); + + //쿠키 자동으로 넘어가게 설정 + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/api/**", configuration); + + return source; + } } From 0597e0744cb78dc262d4fc7fa37406ea88e1b92e Mon Sep 17 00:00:00 2001 From: larama-C Date: Mon, 15 Dec 2025 14:19:40 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20JWT=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=ED=9D=90=EB=A6=84=20=EC=95=88=EC=A0=95=ED=99=94=20=EB=B0=8F=20?= =?UTF-8?q?SecurityContext=20=EC=B2=98=EB=A6=AC=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/security/JwtAuthenticationFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/security/JwtAuthenticationFilter.java b/src/main/java/com/back/web7_9_codecrete_be/global/security/JwtAuthenticationFilter.java index 46c3038b..0ff683a0 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/security/JwtAuthenticationFilter.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/security/JwtAuthenticationFilter.java @@ -65,7 +65,8 @@ protected void doFilterInternal(HttpServletRequest request, SecurityContextHolder.getContext().setAuthentication(auth); } catch (BusinessException ex) { - // Refresh도 실패 → 익명 사용자 유지 + // 재발급 실패 시 SecurityContext 비우기 + SecurityContextHolder.clearContext(); log.debug("Access Token 재발급 실패: {}", ex.getErrorCode()); }