Back-End/Spring

Spring Security cors 이슈

쩡류 2022. 10. 21. 13:47
728x90

사내 오픈마켓 프로젝트를 진행하던 때였다.

나는 인증/인가를 담당하고 있었던 상황이었다

기능 구현을 마치고 프론트 개발자분들과 협업을 진행하던 중, CORS 이슈가 터지고 말았다.

GET Method 이외의 HTTP 메서드 요청을 보낼 때 프론트측에서 CORS 오류 메세지를 수신한다는 것을 들었고,

내가 백엔드 서버의 인증/인가 담당을 하고 있었기에(생각해 보니 상관은 없지만) 해결을 시도하였다.


시도한 방안 1. Spring Security filter에 cors 커스텀 설정 적용하기





기존에는 security 필터 체인을 사용 할 때, WebSecurityConfigurerAdapter 추상클래스를 상속받아 구현을 하였는데, 최근에는 deprecated되어 새로운 방법을 적용하는 것을 권장받는다.

@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
		return httpSecurity

			// csrf 비활성화
			.csrf().disable()
            		// 생략..
            
}


다음과 같이 SecurityFilterChain을 빈으로 등록하면 하나의 필터 체인으로 사용할 수 있게 된다.

이 필터 체인에 다음과 같이 커스텀한 CORS 설정파일을 Bean으로 등록 해 주면, 자동으로 스프링에서 해당 설정값을 cors 설정값으로 사용하게 된다.

@Bean
public CorsConfigurationSource configurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();

    configuration.setAllowedOriginPatterns(Arrays.asList("*"));
    configuration.setAllowedHeaders(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("HEAD","POST","GET","DELETE","PUT"));
    configuration.setAllowCredentials(true);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}




하지만 설정을 마치고 다시 한 번 request를 보내봤지만, 동일한 CORS 이슈를 받는다는 대답이 돌아왔다.


시도한 방안 2. Spring Web MVC에서 제공하는 cors 설정 적용하기




Spring Web MVC 라이브러리에서 제공하는 설정 메서드를 통해서도 CORS 관련 정책을 설정할 수 있었다.

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*").allowedMethods(
                        HttpMethod.GET.name(),
                        HttpMethod.HEAD.name(),
                        HttpMethod.POST.name(),
                        HttpMethod.PUT.name(),
                        HttpMethod.PATCH.name(),
                        HttpMethod.DELETE.name());
    }
}



그런데 사실 찾아보니, 이미 프로젝트 내에 해당 설정 클래스가 존재하고 있었다.

무슨 일인고 하니, 다른 팀원분이 swagger와 프로젝트를 연동하는 과정에서 cors 이슈를 겪고, 해당 설정 파일을 추가 해 놓은 것이었다.

따라서, 일단 여러 ip에서 배포 서버로 request를 보내고 있었으므로 모든 ip 및 메서드에 대해 cors를 enable 시키도록 설정을 했다.

결과적으로 해결이 되었다.

그런데 앞서 사용한 2가지 방법을 모두 사용하면 어떻게 될까?





2가지 방법을 모두 사용해야 하는지에 대해 의구심이 들었고,


테스트를 진행 해 본 결과, 2번째 방법만 사용을 했을 때도 정상적으로 CORS 이슈를 해결할 수 있었다.


그래서 내부적으로 어떻게 작동을 하는지 궁금해서 구글링을 해 보았고, 그 답을 찾을 수 있었다.


즉, spring mvc에서 제공하는 cors 설정값을 지정하고, security에서 제공하는 CorsConfigurationSource 값을 따로 설정하지 않는다면 spring mvc에서 설정한 cors 설정정책을 공유하여 적용을 한다는 내용이 공식문서에 나와있었다.




이로써 궁금증이 해결되었고, 추후 다른 프로젝트에서도 잘 활용할 수 있을 것 같다.