302 Redirect Loop when setting transport-guarantee while behind Elastic Load Balancer
michael_mclean Oct 10, 2016 7:01 AMHi
Have Wildfly 10.0 in docker container, ELB maps port 443 on public side to 8443 on container. Port 80 is mapped to 8080. Both work fine if I have transport-guarantee NONE.
Once I set transport-guarantee in web.xml to CONFIDENTIAL I get a 302 loop. Any advice on how to avoid this loop?
Example of the response from Chrome dev tools, I changed the URL to anonymise a little.
- Generalview source
- Request URL:https://dev.example.com/appname/
- Request Method:GET
- Status Code:302 Found
- Remote Address:52.65.223.135:443
- Response Headersview source
- Connection:keep-alive
- Content-Length:0
- Date:Mon, 10 Oct 2016 10:40:54 GMT
- Location:https://dev.example.com:443/appname/
- Request Headersview source
- Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
- Accept-Encoding:gzip, deflate, sdch, br
- Accept-Language:en-GB,en;q=0.8,en-US;q=0.6,ja;q=0.4
- Cache-Control:max-age=0
- Connection:keep-alive
- Cookie:JSESSIONID=blahblahblah
- Host:dev.example.com
- Upgrade-Insecure-Requests:1
- User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36
You can see the https request gets forwarded to the same URL except with the port number specified. Somehow the user-data-constraint enforcement does not detect this as secure and requests it to hit the secure port. When the browser sends the request I assume it treats the :443 as superfluous, just specifies https and we get into the loop.
Excerpt from standalone.xml showing the redirect for http to http-external. Not really relevant, but without the redirect-socket to https-external the redirect comes back on 8443 which isn't publicly available.
<subsystem xmlns="urn:jboss:domain:undertow:3.0">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" max-post-size="200000000" socket-binding="http" redirect-socket="https-external"/>
<https-listener name="https" max-post-size="200000000" security-realm="ApplicationRealm" socket-binding="https"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<session-cookie secure="true" http-only="true"/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
</subsystem>
Excerpt from standalone.xml showing socket-bindings for https-external
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding name="https-external" port="443"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="localhost" port="25"/>
</outbound-socket-binding>
</socket-binding-group>
Excerpt from web.xml showing the security-constraints
<security-constraint>
<display-name>Sec</display-name>
<web-resource-collection>
<web-resource-name>sec</web-resource-name>
<url-pattern>/*</url-pattern>
<url-pattern>/index.xhtml</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
<http-method>TRACE</http-method>
<http-method>POST</http-method>
<http-method>OPTIONS</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>SiteAccess</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<display-name>UnSec</display-name>
<web-resource-collection>
<web-resource-name>unsec</web-resource-name>
<url-pattern>/sessionTimeout.xhtml</url-pattern>
<url-pattern>/login.xhtml</url-pattern>
<url-pattern>/logint.xhtml</url-pattern>
<url-pattern>/resources/*</url-pattern>
<url-pattern>/javax.faces.resource/*</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
<http-method>TRACE</http-method>
<http-method>POST</http-method>
<http-method>OPTIONS</http-method>
</web-resource-collection>
</security-constraint>