Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
@EnableWebSecurity
Expand All @@ -41,7 +44,7 @@ public SecurityConfig(UserService userService, OAuth2AuthorizedClientService aut
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
.requestMatchers("/", "/question/**", "/login").permitAll()
.requestMatchers("*", "/question/**", "/login").permitAll() // "*"에 대한 설정은 CorsTest를 위함
.anyRequest().authenticated()
)
.oauth2Login(oauth2Login -> oauth2Login
Expand All @@ -60,7 +63,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
// 세션을 생성하지 않도록 설정
.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// JWT 필터 추가
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.addFilter(corsFilter());
return http.build();
}

Expand Down Expand Up @@ -97,8 +101,8 @@ public AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler() {
public LogoutHandler logoutHandler() {
return (HttpServletRequest request, HttpServletResponse response, Authentication authentication) -> {
// 쿠키 삭제
deleteCookie(response, "accessToken");
deleteCookie(response, "refreshToken");
deleteCookie(response, "access_token");
deleteCookie(response, "refresh_token");
};
}

Expand All @@ -118,4 +122,21 @@ private void deleteCookie(HttpServletResponse response, String cookieName) {
cookie.setSecure(true);
response.addCookie(cookie);
}

@Bean
public CorsFilter corsFilter() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("http://localhost:5173"); // 테스트에서 사용되는 도메인 추가
configuration.addAllowedMethod("GET");
configuration.addAllowedMethod("POST");
configuration.addAllowedMethod("PUT");
configuration.addAllowedMethod("PATCH");
configuration.addAllowedMethod("DELETE");
configuration.addAllowedHeader("*"); // 모든 헤더 허용
configuration.setAllowCredentials(true); // 인증 정보 포함 허용

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration); // 모든 경로에 대해 CORS 설정 적용
return new CorsFilter(source);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.mtvs.devlinkbackend.config;

import jakarta.persistence.Id;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import static org.springframework.http.HttpHeaders.*;

@SpringBootTest
@AutoConfigureMockMvc
public class CorsRequestTest {
@Autowired
private MockMvc mockMvc;

@Test
public void testCorsConfig() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.options("/api/some-endpoint")
.header(ORIGIN, "http://localhost:5173")
.header(ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.header().string(ACCESS_CONTROL_ALLOW_ORIGIN, "http://localhost:5173"))
.andExpect(MockMvcResultMatchers.header().string(ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,PUT,DELETE"));
}

@Test
public void testCorsConfig_withDisallowedOrigin() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.options("/api/some-endpoint")
.header(ORIGIN, "http://disallowed-origin.com")
.header(ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.andExpect(MockMvcResultMatchers.status().isForbidden()); // 허용되지 않은 Origin인 경우
}
}