<p>I would like to be able to disable external authorization for a specific path of my App. </p>

<p>Similiar to this SO: <a href="https://stackoverflow.com/questions/54454622/kubernetes-nginx-ingress-disable-basic-auth-for-specific-path">Kubernetes NGINX Ingress: Disable Basic Auth for specific path</a></p>

<p>Only difference is using an external Auth provider (OAuth via Microsoft Azure) and there is a </p>

<p><strong>This is the path that should be reachable by the public</strong></p>

<p><code>/MyPublicPath</code></p>

<p>My ingress.yaml:</p>

<pre><code>apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
  name: myIngressName
  annotations:
    nginx.ingress.kubernetes.io/auth-signin: https://externalprovider/oauth2/sign_in
    nginx.ingress.kubernetes.io/auth-url: https://externalprovider/oauth2/auth
    nginx.ingress.kubernetes.io/auth-request-redirect: https://myapp/context_root/
    nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Access-Token, Set-Cookie, Authorization
spec:
  rules:
  - host: myHostName
    http:
      paths:
      - backend: 
          serviceName: myServiceName
          servicePort: 9080
        path: /
</code></pre>

<p>Can I have it not hit the <a href="https://externalprovider/oauth2/auth" rel="noreferrer">https://externalprovider/oauth2/auth</a> url for just that path? </p>

<p>I've tried using ingress.kubernetes.io/configuration-snippet to set auth_basic to value "off" but that appears to be tied to the basic auth directives not the external ones.</p>

E. Sloss
<p>My experiment showed that it's not required to have two <code>ingress-controllers</code> like <a href="https://stackoverflow.com/users/3156333/crou">Crou</a> mentioned in the previous answer.</p>
<p>One Nginx <code>ingress-controller</code> and two <code>Ingress objects</code> are just enough to do the trick.</p>
<p>The experiment didn't cover the whole solution: the auth provider wasn't deployed so we'll see auth request only, but for checking Ingress part it's not really necessary.</p>
<hr />
<h3>Here are the details [TL;DR]:</h3>
<p><code>Ingress-controller</code> was deployed according to the official <a href="https://kubernetes.github.io/ingress-nginx/deploy/" rel="noreferrer">manual</a>.</p>
<p>Both <code>my1service</code> and <code>my2service</code> are forwarding the traffic to the same Nginx Pod.</p>
<p>I also added <code>rewrite-target</code> <a href="https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target" rel="noreferrer">annotation</a> because my the destination Pod is serving content on path <code>/</code> only.</p>
<p><strong>Ingress1:</strong></p>
<pre><code>apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
  name: myingress1
  annotations:
    nginx.ingress.kubernetes.io/auth-signin: https://externalprovider/oauth2/sign_in
    nginx.ingress.kubernetes.io/auth-url: https://externalprovider/oauth2/auth
    nginx.ingress.kubernetes.io/auth-request-redirect: https://myapp/context_root/
    nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Access-Token, Set-Cookie, Authorization
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myhost.com
    http:
      paths:
      - backend: 
          serviceName: my1service
          servicePort: 80
        path: /

</code></pre>
<p><strong>Ingress2</strong>:</p>
<pre><code>apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
  name: myingress2
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myhost.com
    http:
      paths:
      - backend: 
          serviceName: my2service
          servicePort: 80
        path: /somepath

</code></pre>
<p>Applying them to the cluster gives us the following configuration of ingress-controller:
(I skipped not important lines from the nginx.conf content)</p>
<p>As we can see here, different set of rules is used for each location, so it's possible to have an auth for some path and skip the auth for another, or even have different auth providers for different locations on the same HTTP host.</p>
<p><strong>ingress-controller's nginx.conf:</strong></p>
<pre><code>$ kubectl exec -n ingress-nginx ingress-nginx-controller-7fd7d8df56-xx987 -- cat /etc/nginx/nginx.conf &gt; nginx.conf
$ less nginx.conf

http {
        
        ## start server myhost.com
        server {
                server_name myhost.com ;
                
                location /somepath {
                        # this location doesn't use authentication and responds with the backend content page.
                        
                        set $namespace      &quot;default&quot;;
                        set $ingress_name   &quot;myingress2&quot;;
                        set $service_name   &quot;my2service&quot;;
                        set $service_port   &quot;80&quot;;
                        set $location_path  &quot;/somepath&quot;;
                        
                        set $proxy_upstream_name &quot;default-my2service-80&quot;;
                        set $proxy_host          $proxy_upstream_name;
                        set $pass_access_scheme  $scheme;
                        
                }
                
                location = /_external-auth-Lw {
                        internal;
                        
                        # this location is used for executing authentication requests
                        
                        set $proxy_upstream_name &quot;default-my1service-80&quot;;

                        proxy_set_header            Host                    externalprovider;
                        proxy_set_header            X-Original-URL          $scheme://$http_host$request_uri;
                        proxy_set_header            X-Original-Method       $request_method;
                        proxy_set_header            X-Sent-From             &quot;nginx-ingress-controller&quot;;
                        proxy_set_header            X-Real-IP               $remote_addr;
                        
                        proxy_set_header            X-Forwarded-For        $remote_addr;
                        
                        proxy_set_header            X-Auth-Request-Redirect https://myapp/context_root/;
                        
                        set $target https://externalprovider/oauth2/auth;
                        proxy_pass $target;
                }
                
                location @64e7eef73f135f7a304693e85336f805005c5bc2 {
                        internal;
                        
                        # this location suppose to return authentication error page
                        
                        add_header Set-Cookie $auth_cookie;
                        
                        return 302 https://externalprovider/oauth2/sign_in?rd=$pass_access_scheme://$http_host$escaped_request_uri;
                }
                
                location / {
                        
                        # this location requests for authentication from external source before returning the backend content
                        
                        set $namespace      &quot;default&quot;;
                        set $ingress_name   &quot;myingress1&quot;;
                        set $service_name   &quot;my1service&quot;;
                        set $service_port   &quot;80&quot;;
                        set $location_path  &quot;/&quot;;
                        
                        
                        set $balancer_ewma_score -1;
                        set $proxy_upstream_name &quot;default-my1service-80&quot;;
                        set $proxy_host          $proxy_upstream_name;
                        set $pass_access_scheme  $scheme;
                        
                        set $pass_server_port    $server_port;
                        
                        set $best_http_host      $http_host;
                        set $pass_port           $pass_server_port;
                        
                        set $proxy_alternative_upstream_name &quot;&quot;;
                        
                        # this location requires authentication
                        auth_request        /_external-auth-Lw;
                        auth_request_set    $auth_cookie $upstream_http_set_cookie;
                        add_header          Set-Cookie $auth_cookie;
                        auth_request_set $authHeader0 $upstream_http_x_auth_request_user;
                        proxy_set_header 'X-Auth-Request-User' $authHeader0;
                        auth_request_set $authHeader1 $upstream_http_x_auth_request_email;
                        proxy_set_header 'X-Auth-Request-Email' $authHeader1;
                        auth_request_set $authHeader2 $upstream_http_x_auth_request_access_token;
                        proxy_set_header 'X-Auth-Request-Access-Token' $authHeader2;
                        auth_request_set $authHeader3 $upstream_http_set_cookie;
                        proxy_set_header 'Set-Cookie' $authHeader3;
                        auth_request_set $authHeader4 $upstream_http_authorization;
                        proxy_set_header 'Authorization' $authHeader4;
                        
                        set_escape_uri $escaped_request_uri $request_uri;
                        error_page 401 = @64e7eef73f135f7a304693e85336f805005c5bc2;
                        
                        
                }
                
        }
        ## end server myhost.com
        
}
</code></pre>
<h3>Let's test how it all works:</h3>
<pre><code># ingress-controller IP address is 10.68.0.8

# here I requested / path and internal error and 'externalprovider could not be resolved (3: Host not found)' 
# error tells us that authentication was required, but auth backend is not available. 
# It's expected.

master-node$ curl http://10.68.0.8/ -H &quot;Host: myhost.com&quot;
&lt;html&gt;
&lt;head&gt;&lt;title&gt;500 Internal Server Error&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;center&gt;&lt;h1&gt;500 Internal Server Error&lt;/h1&gt;&lt;/center&gt;
&lt;hr&gt;&lt;center&gt;nginx/1.19.1&lt;/center&gt;
&lt;/body&gt;
&lt;/html&gt;

#controller logs:
$ kubectl logs -n ingress-nginx ingress-nginx-controller-7fd7d8df56-xx987

10.68.0.1 - - [21/Jul/2020:13:17:06 +0000] &quot;GET / HTTP/1.1&quot; 502 0 &quot;-&quot; &quot;curl/7.47.0&quot; 0 0.072 [default-my1service-80] [] - - - - 158e2f959af845b216c399b939d7c2b6
2020/07/21 13:17:06 [error] 689#689: *119718 externalprovider could not be resolved (3: Host not found), client: 10.68.0.1, server: myhost.com, request: &quot;GET / HTTP/1.1&quot;, subrequest: &quot;/_external-auth-Lw&quot;, host: &quot;myhost.com&quot;
2020/07/21 13:17:06 [error] 689#689: *119718 auth request unexpected status: 502 while sending to client, client: 10.68.0.1, server: myhost.com, request: &quot;GET / HTTP/1.1&quot;, host: &quot;myhost.com&quot;
10.68.0.1 - - [21/Jul/2020:13:17:06 +0000] &quot;GET / HTTP/1.1&quot; 500 177 &quot;-&quot; &quot;curl/7.47.0&quot; 74 0.072 [default-my1service-80] [] - - - - 158e2f959af845b216c399b939d7c2b6

# Then I sent a request to /somepath and got a reply without necessity 
# to provide any auth headers. 

$ curl http://10.68.0.8/somepath -H &quot;Host: myhost.com&quot;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome to nginx!&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Welcome to nginx!&lt;/h1&gt;
&lt;p&gt;If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;

#controller logs show the successful reply:
10.68.0.1 - - [21/Jul/2020:13:18:29 +0000] &quot;GET /somepath HTTP/1.1&quot; 200 612 &quot;-&quot; &quot;curl/7.47.0&quot; 82 0.002 [default-my2service-80] [] 10.68.1.3:80 612 0.004 200 3af1d3d48c045be160e2cee8313ebf42

</code></pre>
