SpringSecurity via ELB , Login redirect to http

Circlee7
3 min readAug 28, 2017

--

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에 셋팅하자.

--

--