Learn business/Network

CORS 이슈 해결 :: Spring Security


프로젝트를 진행하면서 CORS 이슈가 발생하여 포스팅을 하면서 정확히 이해하였다. 그러나 스프링 시큐리티를 쓰는 프로젝트에서 Preflight 방식에 이슈가 생겨서 그 내용을 공유하고자 한다.

 

이전 포스팅의 방식대로 CORS 정책에 맞게 코딩을 하였다. 그러나 Spring Security를 사용하는 서비스에서 Preflight Request 방식으로 요청을 할 때, OPTIONS 메소드 방식으로 요청을 하면 Spring Security에서 권한이 없다고 AccessDeniedExeption을 발생시키는 이슈였다. 이번 포스팅에서 Spring Security에서 Preflight Request 방식을 어떻게 해결하였는지 공유하고자 한다.

 

문제의 시작

위 코드를 보면, Filter를 상속 받아서 CORS 정책을 적용한 것을 볼 수 있다. 조금 더 내용을 살펴 보면 CORS 요청 방식 중 Simple Request 방식이면 ORIGIN 헤더를 꺼내서 HttpServletReponse 객체에 담고, Preflight Request 방식이면 허용하고자 하는 헤더를 HttpServletReponse에 담는 것을 볼 수 있다. 그런데 아래와 같은 현상이 일어났다.

Filter를 설정해 주었는데도, 위와 같은 에러가 Console에 찍힘

분명 위 web.xml에 GlobalCorsFilter를 등록해주었는데도, Preflight Request 방식에 대해서 Access-Control-Allow-Origin 헤더 값이 세팅이 안되어 있는 것을 볼 수 있다. 그리고 아래와 같이 웹 브라우저의 네트워크 탭을 열어서 확인하면, OPTIONS 메소드에 대해서 응답 코드가 302으로 리턴된 것을 확인할 수 있었다.

OPTIONS 302 응답 코드

원인 분석

이전 포스팅을 보면 보통 OPTIONS 메소드로 Preflight Request를 던지면, 200 응답 코드로 리턴이 되고 응답 헤더를 통해서 브라우저가 실제 요청을 보낼 수 있을지 없을지를 판단하는 것이 정상이다. 그런데 302 응답 코드로 리턴된 것을 보면 분명 어디선가 중간에 리다이렉트를 시킨 것이 분명했다. 디버깅을 하면서 어디서 리다이텍트를 시키는지 찾다가 Spring Security가 그 범인인 것을 알아냈다. 이번에 작업하는 프로젝트에서 Spring Security를 사용하고 있기 때문에 Preflight Request 방식으로 던진 OPTIONS 메소드가 Spring Security로부터  권한이 없다고 판단돼서 팅겨낸 것이다!

 

해결 방안

바로 구글링을 시작했다. 검색 결과가 많아서 많은 분들이 나와 똑같은 이슈를 겪었구나 했다. 바로 시큐리티에 CORS 설정을 해주면 되는 것인데 JavaConfig로 설정하는 방식과 XML namespace로 하는 방식이 있었다.(구글링하면 너무 자료가 많아서 따로 내용을 담지는 않겠다.) 우리 회사에서는 주로 XML 방식으로 설정을 해주기 때문에 XML 방식으로 세팅을 해주려고 하는데, 이상하게 아래와 같이 Spring Security에 <cors /> 태그가 먹히질 않는 것이다.

<cors/> Element cors is not allowed here

물론 위 방식이 안돼서 JavaConfig 방식도 안돼서 찾다가 결국 Spring Security 버전 문제인 것을 알았다. Spring Security에 CORS 정책이 허용되도록 한 것은 spring-security-config 4.1 버전 이상부터였다. 우리 회사에서는 3.2.6 버전을 사용하기 때문에 위 방식으로는 Preflight Request 방식을 허용할 수 없었다. 그래서 찾다가 <intercept-url> 태그에 OPTIONS 메소드를 모두 허용하도록 조건을 추가하였다. 그러니 CORS 정책의 Preflight Request 방식이 정상적으로 동작하였다.

OPTION Method 허용

해결 방법은 간단하였지만, 의외로 많은 시간 삽질을 하였다. 나와 같은 삽질을 하지 않도록 다른 사람을 위해서 이 글을 남긴다.

 


[참고자료]

https://oddpoet.net/blog/2017/04/27/cors-with-spring-security/

https://stackoverflow.com/questions/40418441/spring-security-cors-filter

https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

'Learn business > Network' 카테고리의 다른 글

Packet Switching을 사용하면 왜 Loss나 Delay가 발생할까?  (0) 2020.06.03
Java Socket Server/Client (TCP 통신)  (3) 2020.03.02
CORS 이슈 해결  (3) 2020.02.16
CORS 정책  (3) 2020.02.09