How do I continue to listen on port 80 (http) but send a 302 redirect to port 443 (https) in a Spring Boot app for the login page. I need this because my application is behind a F5 BigIP proxy that terminates the SSL certificate and sends http requests to my application and currently, I am seeing this behaviour:
This is the current flawed flow:
my Spring Boot application redirects to (HTTP)myapp.example.com/login as a 302 directive to the client
Client requests (HTTP)myapp.example.com/login
F5 BigIP rejects HTTP request
Wanted flow:
my Spring Boot application sends a redirect to (HTTPS)myapp.example.com/login as a 302 to the client (Location=(HTTPS)myapp.example.com/login)
F5 BigIP translates to (HTTP)myapp.example.com/login
I am using Spring Boot version 1.2.8 and my application is behind a F5 BigIp load balancer. The BigIP terminates the SSL certificate and redirects all HTTPS requests to the Spring Boot application listening ONLY on port 80 (http).
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/error", "/js/**", "/css/**", "/img/**", "/help", "/favicon.ico").permitAll()
.anyRequest().hasAuthority("USER")
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login-error")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.logout()
.permitAll();
}
}
I followed the //docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-enable-https documentation adding:
These application.properties:
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.internal-proxies=x\.x\.x\.x|x\.x\.x\.x (I tested without this parameter as well)
BTW: Forcing HTTPS with http.requiresChannel().anyRequest().requiresSecure(); does not work in this case, because I need the second request coming from the F5 BigIp on HTTP to work, using this setting would loop the whole redirecting dance.
I need to configure my app to redirect a client request https://myApp.example.com that is proxied by BigIP to http://myApp.example.com/ To https://myApp.example.com/login so the F5 BigIP accepts it.
This is the result from a curl request: curl -L -b -vk --url https://myApp.example.com --verbose -vs > curl-output.txt 2>&1
STATE: INIT => CONNECT handle 0x440f160; line 1392 (connection #-5000)
* Rebuilt URL to: https://myApp.example.com/
* Added connection 0. The cache now contains 1 members
* STATE: CONNECT => WAITRESOLVE handle 0x440f160; line 1428 (connection #0)
* Trying XXX.XX.XX.XXX...
…
* SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x440f160; line 1596 (connection #0)
} [5 bytes data]
> GET / HTTP/1.1
> Host: myApp.example.com
> User-Agent: curl/7.58.0
> Accept: */*
…
< HTTP/1.1 302
…
< X-XSS-Protection: 1; mode=block
* Added cookie JSESSIONID="4CE1A6F2AB684C6E01774E5289AF2AC0" for domain myApp.example.com, path /, expire 0
< Set-Cookie: JSESSIONID=4CE1A6F2AB684C6E01774E5289AF2AC0;path=/;HttpOnly
****< Location: http://myApp.example.com/login <- this needs to be HTTPS****
< Date: Wed, 09 May 2018 22:30:36 GMT
…
* Connection #0 to host myApp.example.com left intact
* Issue another request to this URL: 'http://myApp.example.com/login' <- this needs to be HTTPS
* STATE: PERFORM => CONNECT handle 0x440f160; line 1949 (connection #-5000)
* Added connection 1. The cache now contains 2 members
* STATE: CONNECT => WAITRESOLVE handle 0x440f160; line 1428 (connection #1)
* Trying XXX.XX.XX.XXX...
* TCP_NODELAY set
* STATE: WAITRESOLVE => WAITCONNECT handle 0x440f160; line 1509 (connection #1)
* connect to XXX.XX.XX.XXX port 80 failed: Connection refused
* Failed to connect to myApp.example.com port 80: Connection refused<= Not the result we want
* Closing connection 1
This problem was never solved on the server side. The systems engineer in charge of the BIG IP changed some configuration settings and now, it's working like they want it to work. I have not asked yet how the Big-IP configuration works. I will post something, if possible, when I find out.