<p>TL;DR Kubernetes Ingress Nginx controller doesn't keep <code>path</code> if underlying service redirects to a relative URL</p>
<p>I have the following Ingress configuration:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: release-name-test-tool
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: &quot;kub.internal.company.com&quot;
      http:
        paths:
        - path: /api/test-tool(/|$)(.*)
          pathType: Prefix
          backend:
            service:
              name: test-tool-service
              port:
                name: http
</code></pre>
<p>Behind <code>test-tool-service</code> is a Spring Boot Application with authorization by OAuth2 protocol.
As a first step, the application redirects to <code>http://server:port/oauth2/authorization/test-tool</code>.</p>
<p>But in the K8S deployment, <code>path</code> part is missed in response's <code>location</code> header  and I receive <code>404</code> after redirection (because there is no Ingress rule for <code>kub.internal.company.com/oauth2(/|$)(.*)</code>)</p>
<p><em>Actual</em>:</p>
<pre><code>cache-control: no-cache, no-store, max-age=0, must-revalidate
content-length: 0
date: Wed, 11 Aug 2021 13:04:24 GMT
expires: 0
location: https://kub.internal.company.com/oauth2/authorization/test-tool
pragma: no-cache
strict-transport-security: max-age=15724800; includeSubDomains
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
</code></pre>
<p><em>Expected</em>:</p>
<pre><code>location: https://kub.internal.company.com/api/test-tool/oauth2/authorization/test-tool
</code></pre>
<p>So, <code>location</code> header in response doesn't contain <code>path</code> from the Ingress configuration.</p>
<p>The same service deployed on bare metal + Nginx <code>proxy_pass</code> configuration works fine.</p>
<p>PS: I found a similar issue in GitHub <a href="https://github.com/kubernetes/ingress-nginx/issues/5076" rel="nofollow noreferrer">https://github.com/kubernetes/ingress-nginx/issues/5076</a> but without an answer.</p>

Sansend
<p>I found two steps solution that works for me:</p>
<ul>
<li>Application side. Spring Boot has a configuration for <a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.use-behind-a-proxy-server" rel="nofollow noreferrer">Running Behind a Front-end Proxy Server</a>. We need to set processing of <strong>X-Forwarded-</strong>* headers to <code>FRAMEWORK</code>(default is <code>NONE</code>). Spring Boot will automatically update the <code>Location</code> header based on the header value:</li>
</ul>
<pre><code>server.forward-headers-strategy=FRAMEWORK
</code></pre>
<ul>
<li>Nginx side. In my K8S setup, not all required <strong>X-Forwarded-</strong>* headers were set. In my case <code>X-Forwarded-Prefix</code> was not configured. Luckily there is a Nginx-Ingress configuration for that - <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#x-forwarded-prefix-header" rel="nofollow noreferrer">https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#x-forwarded-prefix-header</a> :</li>
</ul>
<pre><code>ingress: 
    annotations: 
      nginx.ingress.kubernetes.io/x-forwarded-prefix: /api/test-tool
</code></pre>
<p>How everything works together:</p>
<ul>
<li>Request <code>/api/test-tool/hello</code> is proxied to <code>/hello</code>. Nginx also set <code>X-Forwarded-Prefix : /api/test-tool</code></li>
<li>Spring Boot application handles request for <code>/name</code> and made a redirection using <code>Location</code> header: <code>Location : /oauth2/authorization/test-tool</code></li>
<li>Since we set up processing of <code>X-Forwarded-Prefix</code> Spring Boot adds proxy path to <code>Location</code> : <code>Location : /api/test-tool/oauth2/authorization/test-tool</code></li>
<li>Response is proxied back to the client's browser and we achieve what we want, the browser is redirected to a correct authorization server.</li>
</ul>
