<h2>Background</h2>

<p>I recently migrated my Spring app to Spring Boot (w/ embedded Tomcat), and I am currently moving it into Kubernetes. As a part of the move into Kubernetes, I am separating out the Apache config into its own service and deployment in Kubernetes to act as a proxy for my Spring Boot app.</p>

<p>My current setup is Apache with a LoadBalancer service that accepts requests from the world. This takes those requests and forwards them to my Spring Boot app, which has a ClusterIP service.</p>

<p>Also important to note: my Apache redirects all http to https.</p>

<h2>Issue</h2>

<p>Whenever my Spring Boot app returns a redirect to the client, the location header in the response is http instead of https (only requests made over https will get through the Apache proxy to my app).</p>

<p><em>Example</em>:</p>

<p>Non-logged in user goes to:</p>

<pre><code>https://example.com/admin
</code></pre>

<p>If not authenticated, the admin page will redirect the user to the login page. This SHOULD be one redirect to:</p>

<pre><code>https://example.com/login
</code></pre>

<p>However, as is, my app redirects the user to:</p>

<pre><code>http://example.com/login
</code></pre>

<p>And then the user is redirected again by Apache to:</p>

<pre><code>https://example.com/login
</code></pre>

<h2>What I've Tried</h2>

<p>I've checked my logs to make sure that the requests my app receives include the <code>X-Forwarded-Proto: https</code> header, which from what I understand should make the location header in the redirect response https.</p>

<p>As mentioned in several Stack Overflow posts, I tried adding <code>server.use-forward-headers=true</code> to my <code>application.properties</code> file, but this did nothing. I also tried adding <code>server.tomcat.protocol-header=X-Forwarded-Proto</code> with it, but this did nothing as well (and from what I read, is the default anyway).</p>

<h2>Other Notes</h2>

<ul>
<li>My cluster's <code>networkCIDR</code> is included in Tomcat's list of internal proxies for <code>RemoteIPValve</code></li>
<li><code>X-Forwarded-For</code> doesn't seem to have an impact either, so I think the issue is with all forward headers</li>
</ul>

<p>I figured it out. My mistake was assuming that <code>networkCIDR</code> was the IP address returned by <code>request.getRemoteAddr()</code>, when it was actually my k8s internal cluster IP. This makes sense given that the request is coming from Apache, which is also inside the cluster. The internal cluster IP was NOT in the list of internal proxies, and thus <code>RemoteIPValve</code> was not utilizing the forward headers.</p>

<p>By adding the <code>server.tomcat.internal-proxies</code> property to my <code>application.properties</code> with the default values specified in <code>RemoteIpValve</code> AND my internal cluster IP, everything worked as it should.</p>

<p>See <a href="https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-customize-tomcat-behind-a-proxy-server" rel="noreferrer">https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-customize-tomcat-behind-a-proxy-server</a></p>
