Spring Security 6.1 이후 CORS 설정 문제 해결하기

YuJun Oh·2024년 10월 22일
0

최근 프로젝트에서 "Invalid CORS request"와 함께 403 Forbidden 에러를 마주하게 되었습니다. CORS 설정은 이미 WebMvcConfigurer를 통해 모든 도메인과 모든 요청을 허용해 두었는데, 예상과 달리 브라우저에서 CORS 오류가 발생했습니다. 이 문제를 해결하는 과정에서 Spring Security 6.1의 변화와 CORS 설정 방식을 새롭게 이해할 수 있었습니다. 이 글에서는 문제 상황과 해결 과정을 정리해보겠습니다.


문제 상황: CORS 설정이 적용되지 않음

프로젝트 환경은 Spring Boot와 Spring Security를 사용 중이었고, 다음과 같은 CorsConfig를 사용하여 모든 도메인에서의 요청을 허용한 상태였습니다.

@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOriginPatterns("*")  // 모든 도메인 허용
                        .allowedMethods("*")  // 모든 HTTP 메소드 허용
                        .allowedHeaders("*")  // 모든 헤더 허용
                        .allowCredentials(true);  // 자격 증명 허용
            }
        };
    }
}

Spring Security 설정 역시 다음과 같이 되어 있었는데, 모든 요청을 허용하는 개발 단계의 설정이었습니다.

http
    .cors()  // CORS 설정 활성화
    .csrf().disable()
    .authorizeHttpRequests(authorize -> authorize
        .anyRequest().permitAll()  // 모든 요청을 허용
    );

그런데도 불구하고 CORS 오류가 발생하면서, 브라우저 콘솔에는 "Invalid CORS request"와 403 Forbidden 오류가 떴습니다.


원인 분석: Spring Security 6.1의 변화

문제를 조사하던 중, Spring Security 6.1부터 http.cors() 메서드가 Deprecated 되었고, 곧 제거될 예정이라는 사실을 발견했습니다.

cors() is deprecated since version 6.1 and marked for removal

이는 Spring Security의 CORS 설정 방식이 변경되었음을 의미했습니다. 기존 방식으로는 더 이상 CORS 설정이 제대로 동작하지 않으며, Spring Security가 WebMvcConfigurer에서 정의한 CORS 설정을 무시할 가능성이 있다는 것이었습니다.

해결 과정: Spring Security 6.1에 맞는 CORS 설정 적용

문제를 해결하기 위해 CorsConfigurationSource를 명시적으로 정의하고, 이를 Spring Security에 연결하는 새로운 방식으로 설정을 변경해야 했습니다.

1. CORS 설정을 명시적으로 구성하기

먼저, CORS 규칙을 정의하는 CorsConfigurationSource를 Bean으로 등록했습니다. 이를 통해 Spring Security가 사용할 CORS 규칙을 명확히 설정할 수 있습니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.CorsConfigurationSource;
import java.util.List;

@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOriginPatterns(List.of("*")); // 모든 도메인 허용
        configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE")); // 모든 메소드 허용
        configuration.setAllowedHeaders(List.of("*")); // 모든 헤더 허용
        configuration.setAllowCredentials(true); // 자격 증명 허용

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration); // 모든 경로에 대해 적용
        return source;
    }
}

2. Security 설정에서 CORS 적용

다음으로, Spring Security 설정에서 deprecated된 cors() 대신, CorsConfigurationSource를 명시적으로 사용하여 CORS 설정을 적용했습니다.

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfigurationSource;

@Configuration
public class SecurityConfig {

    private final CorsConfigurationSource corsConfigurationSource;

    public SecurityConfig(CorsConfigurationSource corsConfigurationSource) {
        this.corsConfigurationSource = corsConfigurationSource;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors(cors -> cors.configurationSource(corsConfigurationSource)) // 새로운 방식으로 CORS 설정 적용
            .csrf().disable()  // 필요에 따라 CSRF 비활성화
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().permitAll()  // 모든 요청을 허용 (개발 단계)
            );
        return http.build();
    }
}

이제 CorsConfigurationSource를 통해 CORS 규칙이 명확히 설정되고, Spring Security는 해당 규칙을 기반으로 요청을 처리합니다.


결론: 최신 Spring Security에 맞춘 CORS 설정

Spring Security 6.1부터는 CORS 설정 방식이 변경되면서, 기존의 http.cors() 방식으로는 더 이상 CORS 문제를 해결할 수 없습니다. 대신, CorsConfigurationSource를 사용하여 CORS 규칙을 명시적으로 정의하고, 이를 Spring Security 설정에 적용해야 합니다.

이 방법을 적용한 후에는 더 이상 "Invalid CORS request"나 403 오류가 발생하지 않았습니다. 만약 여러분도 Spring Security 6.1 이후 CORS 문제를 겪고 있다면, 이와 같은 방식으로 설정을 수정해보세요. 최신 버전에 맞게 코드를 업데이트함으로써 문제를 해결할 수 있습니다.


참고

0개의 댓글

관련 채용 정보