title: How to perform custom authentication with kubernetes Ingress
body: <p>I have deployed few services in kubernetes and using NGINX ingress to access outside.(Using EC2 instance for all cluster setup). Able to access service through host tied with ingress. Now instead of accessing the svc directly I am trying to add authentication and before accessing the service. And redirecting to login page , user enters credentials and should redirect to the asked page. The following code snipet I I tried so far. Please guide to find solution.</p>
  <p>my-ingress.yml</p>
  <pre><code>apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: my-ingress
    namespace: mynamespace  
    annotations:
      nginx.ingress.kubernetes.io/rewrite-target: /
      nginx.ingress.kubernetes.io/affinity: cookie
      nginx.ingress.kubernetes.io/session-cookie-name: JSESSIONID
      nginx.ingress.kubernetes.io/ssl-passthrough: &quot;false&quot;
      nginx.ingress.kubernetes.io/ssl-redirect: &quot;true&quot;
      nginx.ingress.kubernetes.io/force-ssl-redirect: &quot;true&quot;
      kubernetes.io/ingress.class: &quot;nginx&quot;
      kubernetes.io/ingress.allow-http: &quot;false&quot;
      nginx.ingress.kubernetes.io/auth-signin: &quot;https://auth.mysite.domain/api/auth/login&quot;  #will show login page
      nginx.ingress.kubernetes.io/auth-url: &quot;https://auth.mysite.domain/api/auth/token/validate&quot;
      nginx.ingress.kubernetes.io/auth-response-headers: &quot;authorization&quot;    
      
  spec:
    tls:
    - hosts: 
      - mysite.domain
      #secretName: ${TLS_TOKEN_NAME}
    rules:
    - host: a.mysite.domain
      http:
        paths:
          - path: /
            backend:
              serviceName: myservice1
              servicePort: 9090 
   
  </code></pre>
  <p>so first it will call &quot;/token/validate&quot; and will get unauthorized then  got to &quot;auth/login&quot; and login page will show
  after entering credentials going to &quot;/token/validate&quot; and again login page. Actually should redirect to the called page.</p>
  <p>How to achieve this?[If after successful auth if we can add header in called ling I think can solve but not sure how]</p>
  <p>backend: Java Spring</p>
  <pre><code>@RequestMapping(&quot;login&quot;)  
  public String login() {  
      return &quot;login.html&quot;;  
  } 
  </code></pre>
  <p>login.html</p>
  <pre><code>    &lt;form action=&quot;validate-user&quot; method=&quot;post&quot; enctype=&quot;application/x-www-form-urlencoded&quot;&gt;  
          &lt;label for=&quot;username&quot;&gt;Username&lt;/label&gt;  
          &lt;input type=&quot;text&quot; id=&quot;username&quot; value=&quot;admin&quot; name=&quot;username&quot; autofocus=&quot;autofocus&quot; /&gt;  &lt;br&gt;
          &lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;  
          &lt;input type=&quot;password&quot; id=&quot;password&quot; value=&quot;password&quot; name=&quot;password&quot; /&gt;  &lt;br&gt;
          
          &lt;input id=&quot;submit&quot; type=&quot;submit&quot; value=&quot;Log in&quot; /&gt;  
      &lt;/form&gt; 
  </code></pre>
  <p>backend: Java Spring</p>
  <pre><code>@PostMapping(&quot;validate-user&quot;)
  @ResponseBody
  public ResponseEntity&lt;?&gt; validateUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
                  ...
                  
      HttpStatus httpStatus=HttpStatus.FOUND;
      //calling authentication api and validating
          
      //else
      httpStatus=HttpStatus.UNAUTHORIZED;
      HttpHeaders responseHeaders= new HttpHeaders();
      responseHeaders.set(&quot;Authoriztion&quot;, token);
                  
      //responseHeaders.setLocation(new URI(&quot;https://a.mysite.domain&quot;)); ALSO TRIED BUT NOT WORKED
      return new ResponseEntity&lt;&gt;(responseHeaders,httpStatus);        
          
          }
  </code></pre>
  <p><strong>UPDATE1:</strong> I am using my own custom auth api, if I am hitting the url with custom header &quot;Authorization&quot;:&quot;bearer token&quot; from postman then response is ok, but from from browser not possible, So from upstream svc only(after successfull login) the header should include in redirect page that how can we do?<br />
  ANY ANNOTATION AM I MISSING?</p>
  <p><strong>UPDATE2:</strong> While redirecting after successful auth I am passing token as query string like <code>responseHeaders.setLocation(new URI(&quot;https://a.mysite.domain/?access_token=&quot;+token)</code> and after redirecting its going to validate. After successful validation going to downstream svc[expected]. But when that svc is routing say <code>a.mysite.domain/route1</code> then query string is gone and auth svc not able to get token hence <code>401</code> again. It should be like <code>a.mysite.domain/route1/?access_token=token</code>. Any way is there to do that? If every route will have same query string then will work.[This is my PLAN-B...but still passwing token is header is my priority]</p>
  <p><strong>UPDATE3:</strong> I tried with annotations like:</p>
  <pre><code>nginx.ingress.kubernetes.io/auth-signin: 'https://auth.example.com/api/auth-service-ui/login'
  nginx.ingress.kubernetes.io/auth-response-headers: 'UserID, Authorization, authorization'
  nginx.ingress.kubernetes.io/auth-snippet: |
        auth_request_set $token $upstream_http_authorization;
        proxy_set_header Foo-Header1 $token; //not showing as request header AND this value only need LOOKS $token val is missed
        proxy_set_header Foo-Header headerfoo1; //showing as request header OK
        more_set_input_headers  'Authorization: $token';//not showing as request header AND this value only need LOOKS $token val is missed
  
  nginx.ingress.kubernetes.io/configuration-snippet: |
        auth_request_set $token1 $upstream_http_authorization;
        add_header  authorization2 QQQAAQ1; //showing as response header OK no use
        add_header  authorization $token; //showing as response header OK how to send as request header on next call
        more_set_input_headers  'Authorization11: uuu1';//showing as request header in next call
        more_set_input_headers  'Authorization: $token1';//not showing as request header and need this val ONLY
  </code></pre>
  <p>**What annotation I missed?</p>
  <p><strong>UPDATE4</strong>
  PLAN-C: Now trying to store jwt token in cookies.</p>
  <pre><code> nginx.ingress.kubernetes.io/configuration-snippet: |
        auth_request_set $token5 $upstream_http_authorization;    
        add_header Set-Cookie &quot;JWT_TOKEN=$token5&quot;;
  </code></pre>
  <p>In every request the same cookie is set but in browser its storing everytime. ie multiple cookies of same. How to set only once?</p>