Keycloak 연동과 Spring Security 에서 발생한 cors


백오피스 개발하면서 발생했던 에러 사항중 하나인 CORS 에러에 대해서 공유하려고 합니다.

백오피스 구조로써 2가지를 아키텍쳐를 생각해두고 있는데 첫번째의 경우는

이렇게 백엔드(Spring Boot)와 프론트엔드(Vue3)를 같이 빌드해서 실행하는 구조와

두번째의 경우는 백엔드(Spring Boot)와 프론트엔드(Vue3)를 분리해서 따로 빌드 및 실행하는 구조가 있습니다.

여기서 첫번째의 경우 프론트와 백엔드가 같은 오리진(프로토콜+호스트명+포트)에 있고

두번째의 경우는 오리진이 (192.168.0.9:8080, 192.168.0.9:80)으로 다릅니다.

여기서 로그인이 안 되어 있는 경우 제가 상정했던 처리 방식은 spring security가 SSO(Keycloak) 서버로 리다이렉트 시킬 때

프론트엔드(vue)에서의 요청도 그 리다이렉트를 따르길 바랬습니다. 첫번째의 경우는 생각했던대로 작동하는 반면

두번째의 경우 CORS (MissingOriginHeader)에러가 발생하 원인을 분석하던 중

https://w3c.github.io/webappsec-cors-for-developers/#identify-yourself-and-get-permission-simple-request-read-permissions

(w3c) 웹표준에 따르면 

If a cross-origin resource redirects to another resource at a new origin, the browser will set the value of the Origin header to null after redirecting. 

cors 가 새 오리진으로 리다이렉션 되는 경우, 브라우저는 Origin 헤더를 null로 설정하는 규약이 있는 걸 알게 되었습니다.

요약하자면

vue3에서 axios를 통해 스프링과 통신하며 스프링 세큐리티로 Oauth 설정을 했을 때,
로그인이 되어 있지 않은 상태이면 스프링은 리퀘스트를 Keycloak으로 리다이렉트 시키게 됨
하지만 (w3c)웹 표준에 따르면 300코드를 받으면 브라우저가 origin을 null로 세팅해서 MissingOriginHeader 에러가 발생함

그래서 이 문제를 해결하기 위해서 조사하던중

https://stackoverflow.com/questions/72382892/access-to-fetch-at-https-accounts-google-com-o-oauth2-v2-auth-has-been-blocked

위 링크를 참고해서 현재 대응하고 있습니다. 

내용은 아래와 같습니다.

프론트에서 로그인을 수행하면 별도의 로그인 페이지(keycloak)로 리다이렉트 시켜서 오리진이 같도록 한 다음

인증후에는 keycloak에서 세션을 관리하고 있고, 로그인 유무는 JSESSIONID 쿠키의 유무로 판단해서 개발을 진행하려고 합니다.

참고로 별도의 로그인 페이지가 스프링이 아닌 이유는 Keycloak에서 로그인 페이지를 제공해주고 있기 때문입니다.

 

되돌아가기 수정