Languages
[Edit]
EN

Spring Boot - forward schema / protocol via apache2 proxy

4 points
Created by:
Root-ssh
121070

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).

X-Forwarded-Proto header in Spring Boot with Apache 2.
X-Forwarded-Proto header in Spring Boot with Apache 2.

Quick solution:

// 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:

  @Bean
  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:

  @RequestMapping(value = "/example", produces = MediaType.TEXT_PLAIN_VALUE)
  @ResponseBody
  public String example(HttpServletRequest request) {

      String protocol = request.getScheme();  // will return http or https

      // ...
  }

 

Simple steps:

  1. be sure that, apache2 forwards protocol information with X-Forwarded-Proto header,
  2. create configuration bean in Spring Boot Application.

Note: above configuration was tested under Debina 10, Apache 2.4 and Spring Boot 2.4.

 

Practical example

If X-Forwarded-Proto is not supported in apache2 server we can add it manually.

Set http in HTTP VirtuaServer and https in HTTPS VirtuaServer,

Hint: do not forget to restart server or reload configurations after changes.

/etc/apache2/sites-enabled/my-domain.com.conf file example:

<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:

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;

@Controller
public class ExampleController
{
    @RequestMapping(
            value = "/example",
            method = RequestMethod.GET,
            produces = MediaType.TEXT_PLAIN_VALUE
    )
    @ResponseBody
    public String example(HttpServletRequest request) {

        String protocol = request.getScheme(); // returns forwarded protocol if set in header

        return "used protocol: " + protocol;
    }
}

SpringConfig.java file example:

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;

@Configuration
public class SpringConfig {

    @Bean
    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;
    }
}

References

  1. X-Forwarded-Proto - MDN Docs

Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join