Spring Boot 프록시 X-Forwarded-* 헤더 처리

유알·2023년 11월 26일
0

[Spring]

목록 보기
17/17
post-thumbnail

문제 상황

앞단에 spring cloud gateway를 기반으로 하는 API Gateway가 존재하고, 로그인 관련 요청이 오게 되면, 뒷단에 있는 로그인 서비스로 포워딩 하는 형식으로 동작한다.
뒷단에 있는 로그인 서비스는, 외부에 공개되지 않도록 하였다.

문제는 Google로 인증 요청을 하는 302 응답시, param에 인증 성공시 응답을 보낼 엔드포인트를 담아 보내야 하는데, 나의 Account Service는 자신의 주소인 localhost:29090을 응답하는 것이었다.

이렇게 되면, 두가지 문제가 발생한다.

  • 구글에 미리 허용되는 리다이렉트 주소를 등록해야하는데, Account Service가 아닌 Api Proxy의 호스트만 등록되어 있다.
  • 애초에 Account Service는 외부에 공개되어 있지 않으므로, 등록할 수도, 리다이렉트 할 수도 없다.

해결 방법

X-Forwareded Header 설정

Http Header 중에 X-Forwarded-*로 시작하는 헤더가 있다.
이는 앞단에 로드 밸런서나 프록시를 둘 경우에, 최초 요청했던 요청의 정보를 담는 헤더이다.

Spring Cloud Gateway에서는 다음과 같은 필터가 기본적으로 제공되며, 기본값이 true로 되어 있다.

https://cloud.spring.io/spring-cloud-gateway/2.1.x/multi/multi__httpheadersfilters.html

  • X-Forwarded-For : 통과한 ip 주소들
  • X-Forwarded-Host : 전달된 서버의 도메인 명
  • X-Forwarded-Proto : 전달된 프로토콜

이렇게 하면, Gateway에서 포워딩을 할때 헤더들을 붙여준다.

서비스 서버에서 property 설정

spring boot 3.1.4 기준입니다.

server:
  forward-headers-strategy: framework
  tomcat:
    remoteip:
      host-header: X-Forwarded-Host
      port-header: X-Forwarded-Port
      protocol-header: X-Forwarded-Proto
      remote-ip-header: X-Forwarded-For
    use-relative-redirects: true

forward-headers-strategy

다음과 같은 설정이 있다

  • framework : 스프링 자체 필터를 활용한다.
  • Native : tomcat, jetty, netty 등 컨테이너의 기본 자원을 활용한다.
  • None : 안쓴다.

참조 : https://stackoverflow.com/questions/68318269/spring-server-forward-headers-strategy-native-vs-framework

use-relative-redirects

리다이렉트 시에, 절대 경로가 아니라 상대 경로를 사용한다. 필수인 것은 아니지만 난 그냥 넣었다.

사용

일단 두개의 서버를 띄우고, ModularTravelApplication 쪽의 필터 하나에다가 브레이크 포인트를 걸어보았다.

localhost:8080/account/login/oauth2/authorization/google

localhost:29090으로 띄워져 있는데에도 불구하고, HttpServletRequest에서 프록시의 정보를 잘 표시하는 것을 볼 수 잇다.

profile
더 좋은 구조를 고민하는 개발자 입니다

0개의 댓글