ELB를 거친 WAS 에서 https로그인시에 http로 바뀐다. -_-;
추가 2018.04.27
시스템 인프라 구성을 볼 수 업는 상태여서 파악이 안되었지만.
추후 확인해보니 ELB Listener 에서 HTTPS -> HTTP 로 설정되어 있었다.
개발중.. ELB를 거친 Tomcat — spring boot — spring security
https로 ELB를 통해 어플리케이션에 접근시 로그인을 하면
http로 바뀌는 경우가 발생하였다.
추가 2018.04.27
http 로 변경하는 부분은 Spring Security 의 portMapper 에서 request Scheme
을 값을 참조하여 https, http 로 리다이렉트 url을 만들기 때문이다.
애초에 모든 http 접근을 https 로 변경 해주도록 해도 해결되는 문제다.
간단하게 유추한 발생 원인은 WAS에서 https로 인식되지 않는다 라는 것이었는데.
원인의 원인. 왜 https로 인식되지 않는지에 대해 다시 한번 유추해 보았다.
애초에 ELB를 거치면서 https 가 아닌 http로 WAS를 호출하는게 아닐까?
-_- 맞다..
추가 2018.04.27
AWS ELB의 Listener 구성 부터 보았으면. 해매지 않았을 문제.
ELB listener 구성에서 https -> http로 설정되어있었다.
AWS ELB를 거치며 HTTPS 인코딩되었던 전문은 decoding되고 WAS 로 넘어오게 된다.
이때 ELB나 여타 프록시에서 처리전 원본 Request정보를 넘겨줘야지
뒷단인 서버나 WAS 에서도 처리를 할텐데… 라고 생각했더니.
있다.
흠 .. 표준인지 아닌지.. 실제 요청ip 를 X-Forwarded-For로 넘기는 proxy도 있고 X-real-ip로 넘기는 곳도 있단다.
정리!.
일단.
x-forwarded-for는 ip 정보고
x-forwarded-proto는 protocol 정보이다.
AWS ELB는 위의 두 정보들을 전부 넘겨주고 있다.
Spring Security의 successHandler에서 내부적으로
(HttpServletRequest) request.isSecure() 를 참조하는지 .
redirect될때 https로 로그인 요청하였더라도 http로 리다이렉트 된다.
그렇다면 request 에 대한 secure설정은 어떻게 해야하나.
tomcat 의 server.xml에 아래 한줄을 추가하면 된다.
<Valve className=”org.apache.catalina.valves.RemoteIpValve” protocolHeader=”x-forwarded-proto” />
request header의 x-forwarded-proto 값으로 protocol을 인식한다.
Engine, Host, or Context 안에 넣어야 한다.
아래를 참고하자
Spring boot의 embeded tomcat인 경우도 뭐.
application.properties에 server.tomcat.protocol-header=x-forwarded-proto
라고 입력하면 되겠다.
tomcat이 아닌 was에 설정하는 방법은 아래와 같다.
참고https://github.com/BroadleafCommerce/BroadleafCommerce/issues/424
phillipuniverse ‘s comment
Tomcat
server.xml (http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html)
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" />
WebLogic
It looks like WebLogic expects a WL-Proxy-SSL
header to be set to achieve the same behavior as Tomcat expecting the X-Forwarded-Proto
(assuming that's how you've configured the RemoteIpValve). Although, Oracle recommends using the mod_wl
Apache module rather than just proxying over mod_ajp or mod_jk which allows you to set a WLProxySSL
directive in your https VirtualHost, making it even easier: http://docs.oracle.com/cd/E13222_01/wls/docs81/plugins/plugin_params.html#1143055.
JBoss
jboss-web.xml
<jboss-web>
<valve>
<class-name>org.apache.catalina.valves.RemoteIpValve</class-name>
<param>
<param-name>protocolHeader</param-name>
<param-value>x-forwarded-proto</param-value>
</param>
</valve>
...
</jboss-web>
Jetty
jetty-web.xml (http://wiki.eclipse.org/Jetty/Tutorial/Apache)
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
...
<Set name="forwarded">true</Set>
</New>
</Arg>
</Call>
Glassfish (3.1.2+)
Good article describing config for ❤.1.2: http://stupidfredtricks.blogspot.com/2012/10/glassfish-31x-behind-ssl-terminating.html. Also, looks like an active bug opened a couple weeks ago: https://java.net/jira/browse/GLASSFISH-20842
domain.xml
<http default-virtual-server="server" max-connections="250" scheme-mapping="X-Forwarded-Proto">
- 추가
elb 를 통해 https 도메인으로도 접근하고 싶고. http ip로 해당 was 에 직접 접근하고 싶기도 하다면.
PortMapper를 익명클래스로 상속생성하여 Spring security의 HttpSecurity객체와 등록되어 사용하는 여러 Handler에 셋팅하자.