Spring Boot - forward user protocol information via apache2 proxy
In this article, we would like to show how to configure Apache2 server with Spring Boot Application to forward information about used protocol in current user request (HTTP or HTTPS information forwarding).

Quick solution:
xxxxxxxxxx
// In the Apache2 VirtualHost:
<VirtualHost *:80>
...
RequestHeader set X-Forwarded-Proto http
...
<VirtualHost *:443>
...
RequestHeader set X-Forwarded-Proto https
...
// In the Spring Boot Configuration:
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(new ForwardedHeaderFilter());
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
return registration;
}
// In the Spring Boot Controller:
value = "/example", produces = MediaType.TEXT_PLAIN_VALUE) (
public String example(HttpServletRequest request) {
String protocol = request.getScheme(); // will return http or https
// ...
}
Simple steps:
- be sure that, apache2 forwards protocol information with
X-Forwarded-Proto
header, - create configuration bean in Spring Boot Application.
Note: above configuration was tested under Debina 10, Apache 2.4 and Spring Boot 2.4.
If X-Forwarded-Proto
is not supported in apache2 server but we can add it manually. We can do it by setting http
in HTTP VirtuaServer and https
in HTTPS VirtuaServer.
Check the below files to know what is necessary configure it.
Hint: do not forget to restart server or reload configurations after changes.
/etc/apache2/sites-enabled/my-domain.com.conf
file example:
xxxxxxxxxx
<VirtualHost *:80>
# HTTP mode:
ServerName my-domain.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
RequestHeader set X-Forwarded-Proto http
</VirtualHost>
<VirtualHost *:443>
# HTTP mode:
ServerName my-domain.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
# HTTPS mode:
Protocols h2 http/1.1
SSLEngine on
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCertificateKeyFile "/path/to/private_key.pem"
SSLCertificateFile "/path/to/certificate.pem"
RequestHeader set X-Forwarded-Proto https
</VirtualHost>
ExampleController.java
file example:
xxxxxxxxxx
package com.example;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
public class ExampleController
{
(
value = "/example",
method = RequestMethod.GET,
produces = MediaType.TEXT_PLAIN_VALUE
)
public String example(HttpServletRequest request) {
String protocol = request.getScheme(); // returns forwarded protocol if set in header
return "used protocol: " + protocol;
}
}
SpringConfig.java
file example:
xxxxxxxxxx
package com.example;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.filter.ForwardedHeaderFilter;
import javax.servlet.DispatcherType;
public class SpringConfig {
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(new ForwardedHeaderFilter());
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
return registration;
}
}