← 글 목록

nginx 뒤에 붙였더니 로그인하면 http로 튕긴다

HTTPS는 nginx에서 처리하고 뒤에 톰캣(8080)을 붙이는 흔한 구성이다. 페이지는 잘 열리는데 로그인만 하면 주소가 http://로 바뀌었다. HSTS가 켜져 있는 브라우저에서는 다시 https로 돌아오긴 하는데, 아무튼 리다이렉트가 이상하게 나가고 있었다.

왜 그런가

브라우저 → nginx 구간은 https지만, nginx → 톰캣 구간은 그냥 http다. 톰캣은 자기가 http 요청을 받았다고 생각하니까, 스프링 시큐리티가 로그인 성공 후 리다이렉트 주소를 만들 때 http://도메인/...으로 만든다.

nginx 설정에는 이미 이걸 넣어 두고 있었다.

proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

문제는 헤더를 보내기만 하고 받는 쪽에서 안 읽고 있었다는 것.

해결

내장 톰캣(java -jar)으로 띄우는 경우는 설정 한 줄이면 된다.

server:
  forward-headers-strategy: native

외부 톰캣에 WAR로 올리는 경우는 이 설정이 안 먹는다. server.* 설정은 내장 서버용이라서. 이때는 톰캣 conf/server.xml의 <Host> 안에 밸브를 넣는다.

<Valve className="org.apache.catalina.valves.RemoteIpValve" />

기본값으로 X-Forwarded-For, X-Forwarded-Proto를 읽고, 127.0.0.1 같은 내부 주소에서 온 요청만 믿는다. nginx가 같은 서버에 있으면 따로 손댈 게 없다.

처음에는 application.yml에 넣었는데 왜 안 되지 하고 한참 봤다. WAR 배포면 톰캣 설정을 봐야 한다는 걸 이번에 확실히 기억하게 됐다.

확인 방법

curl -s -o /dev/null -w "%{redirect_url}\n" https://내도메인/admin

https://로 시작하는 로그인 주소가 나오면 정상이다.