Https Redirect: Spring boot app running on GKE

In this we will talk about how to redirect http traffic to https.

For this we will be using a Spring boot app which is running on Google kubernetes engine. We will also use the Tuckey url re-writer.

For this we assume you already know how to run a spring boot service on GKE. A sample repository can be found here

Extend the UrlRewriteFilter which re-writes the url based on the rules provided in the xml config.

import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.UrlRewriteFilter;
import org.tuckey.web.filters.urlrewrite.UrlRewriter;

import javax.servlet.*;
import java.io.InputStream;
@Component
@Log4j2
public class HttpsUrlRewriteFilter extends UrlRewriteFilter {

@Autowired
Environment env;

private UrlRewriter urlRewriter;


@Override
public void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
try {
String urlrewriteFileName = "urlrewrite.xml";
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(urlrewriteFileName);
Conf conf1 = new Conf(filterConfig.getServletContext(), inputStream, urlrewriteFileName, "");
urlRewriter = new UrlRewriter(conf1);
} catch (Exception e) {
throw new ServletException(e);
}
}

@Override
public UrlRewriter getUrlRewriter(ServletRequest request, ServletResponse response, FilterChain chain) {
return urlRewriter;
}

@Override
public void destroyUrlRewriter() {
if(urlRewriter != null)
urlRewriter.destroy();
}
}

Below is one of the rule configuration which we have used in multiple apps.

In the rule you can see 3 different urls which we are re-writing. The http rules are obvious but why are we re-writing https://example.com rule.

As we want to run this service behind gke ingress controller which only supports one https certificate per domain and also doesn’t support wild card certificates. We had generated the certificate using https://www.example.com so any url without www will give certificate error.

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE urlrewrite
PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
"http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">


<urlrewrite>


<rule>
<name>Domain Name Check</name>
<condition type="request-url" operator="equal">(^http://example.com|^http://www.example.com|^https://example.com)</condition>
<from>^(.*)$</from>
<to type="redirect">https://www.example.com$1</to>
</rule>


</urlrewrite>

If you deploy your spring boot application using just above two changes then ingress will not be able to ping your service.

The ping request expects 200 response code, where as this would give 302 which is a redirect response. The reason behind this is GKE ingress does the ssl termination and ingress to GKE is http request.

The last piece of trick is to set following properties in your spring boot app

server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto

Above would ensure that your service gets the protocol and ip address of the end client and not the ingress server.

If you follow the above steps you should be able to re-direct any of your http endpoints to https.

Let us know if have some issues settings things up.

Follow us on twitter: https://twitter.com/k8scaleio

Simplifying writing cloud connected Apps.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store