Kubernetes NGINX入口:禁用特定路径的外部身份验证

Kubernetes NGINX入口:禁用特定路径的外部身份验证,nginx,kubernetes,oauth-2.0,kubernetes-ingress,Nginx,Kubernetes,Oauth 2.0,Kubernetes Ingress,我希望能够禁用应用程序特定路径的外部授权 与此类似,因此: 唯一的区别是使用外部身份验证提供程序(OAuth通过Microsoft Azure),并且存在 这是公众应该能够访问的路径 /MyPublicPath 我的名字。亚马尔: apiVersion: extensions/v1beta1 kind: Ingress metadata: name: myIngressName annotations: nginx.ingress.kubernetes.io/auth-sign

我希望能够禁用应用程序特定路径的外部授权

与此类似,因此:

唯一的区别是使用外部身份验证提供程序(OAuth通过Microsoft Azure),并且存在

这是公众应该能够访问的路径

/MyPublicPath

我的名字。亚马尔:

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: /
我可以让它不点击该路径的url吗


我已经尝试使用ingres.kubernetes.io/configuration-snippet将auth_basic设置为值“off”但是,这似乎与基本身份验证指令有关,而不是与外部指令有关。

因为您已经有了
入口,并且路径是
/
,因此无法在
上禁用基本身份验证https://externalprovider/oauth2/auth

有关最佳解释,请参阅提供的答案。

为此,您需要设置另一个
入口
,并将其配置为禁用基本身份验证。
你也可以在堆栈上检查这个问题和这个问题。

我的实验表明,它不需要像前面的答案中提到的那样有两个
入口控制器

一个Nginx
ingres控制器
和两个
ingres对象
就足够了

实验并没有涵盖整个解决方案:未部署身份验证提供程序,因此我们将仅看到身份验证请求,但对于检查入口部分,这并不是真正必要的


以下是详细信息[TL;DR]: 根据官方消息,已部署入口控制器

my1service
my2service
都在将流量转发到同一个Nginx Pod

我还添加了
rewrite target
,因为我的目标Pod仅提供路径
/
上的内容

入口1:

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: /

$ kubectl exec -n ingress-nginx ingress-nginx-controller-7fd7d8df56-xx987 -- cat /etc/nginx/nginx.conf > 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      "default";
                        set $ingress_name   "myingress2";
                        set $service_name   "my2service";
                        set $service_port   "80";
                        set $location_path  "/somepath";
                        
                        set $proxy_upstream_name "default-my2service-80";
                        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 "default-my1service-80";

                        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             "nginx-ingress-controller";
                        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      "default";
                        set $ingress_name   "myingress1";
                        set $service_name   "my1service";
                        set $service_port   "80";
                        set $location_path  "/";
                        
                        
                        set $balancer_ewma_score -1;
                        set $proxy_upstream_name "default-my1service-80";
                        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 "";
                        
                        # 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
        
}
入口2

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

将它们应用到集群中,我们可以看到入口控制器的以下配置: (我跳过了nginx.conf内容中不重要的行)

正如我们在这里所看到的,每个位置使用不同的规则集,因此可以对某些路径使用身份验证,而对另一个路径跳过身份验证,甚至可以对同一HTTP主机上的不同位置使用不同的身份验证提供器

入口控制器的nginx.conf:

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: /

$ kubectl exec -n ingress-nginx ingress-nginx-controller-7fd7d8df56-xx987 -- cat /etc/nginx/nginx.conf > 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      "default";
                        set $ingress_name   "myingress2";
                        set $service_name   "my2service";
                        set $service_port   "80";
                        set $location_path  "/somepath";
                        
                        set $proxy_upstream_name "default-my2service-80";
                        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 "default-my1service-80";

                        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             "nginx-ingress-controller";
                        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      "default";
                        set $ingress_name   "myingress1";
                        set $service_name   "my1service";
                        set $service_port   "80";
                        set $location_path  "/";
                        
                        
                        set $balancer_ewma_score -1;
                        set $proxy_upstream_name "default-my1service-80";
                        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 "";
                        
                        # 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
        
}
让我们测试一下它是如何工作的:
#入口控制器IP地址为10.68.0.8
#这里我请求了/path和内部错误,并且“无法解析externalprovider(3:找不到主机)”
#错误告诉我们需要身份验证,但身份验证后端不可用。
#这是意料之中的。
主节点$curlhttp://10.68.0.8/ -H“主机:myhost.com”
500内部服务器错误
500内部服务器错误

nginx/1.19.1 #控制器日志: $kubectl日志-n入口nginx入口nginx控制器-7fd7d8df56-xx987 10.68.0.1--[21/Jul/2020:13:17:06+0000]“GET/HTTP/1.1”5020-“curl/7.47.0”0.072[default-my1service-80][]--158e2f959af845b216c399b939d7c2b6 2020/07/21 13:17:06[错误]689#689:*无法解析119718外部提供程序(3:找不到主机),客户端:10.68.0.1,服务器:myhost.com,请求:“GET/HTTP/1.1”,子请求:“/_external-auth-Lw”,主机:“myhost.com” 2020/07/21 13:17:06[错误]689#689:*119718身份验证请求意外状态:502发送到客户端时,客户端:10.68.0.1,服务器:myhost.com,请求:“GET/HTTP/1.1”,主机:“myhost.com” 10.68.0.1--[21/Jul/2020:13:17:06+0000]“GET/HTTP/1.1”500 177-“curl/7.47.0”74 0.072[default-my1service-80][]--158e2f959af845b216c399b939d7c2b6 #然后我向/somepath发送了一个请求,并在没有必要的情况下得到了回复 #提供任何身份验证标头。 $curlhttp://10.68.0.8/somepath -H“主机:myhost.com” 欢迎来到nginx! 欢迎来到nginx! 如果您看到此页面,则nginx web服务器已成功安装,并且 工作需要进一步配置

#控制器日志显示成功的回复: 10.68.0.1--[21/Jul/2020:13:18:29+0000]“GET/somepath HTTP/1.1”200 612-“curl/7.47.0”82 0.002[default-my2service-80][]10.68.1.3:80 612 0.004 200 3af1d3d48c045be160e2cee8313ebf42
我也遇到了同样的问题,我在我的ingres.yaml文件及其工作环境中添加了下面的代码片段

nginx.ingress.kubernetes.io/auth-snippet: | 
    if ( $request_uri = "/nonmember" ) {
        return 200;
    }

尝试设置第二个
入口
,该入口将仅配置为具有禁用身份验证的路径。@cru最终成为解决方案。我已经发布了一个答案,如果你需要任何其他信息,请询问。请查看我的评论