Kubernetes NGINX入口:禁用特定路径的外部身份验证
我希望能够禁用应用程序特定路径的外部授权 与此类似,因此: 唯一的区别是使用外部身份验证提供程序(OAuth通过Microsoft Azure),并且存在 这是公众应该能够访问的路径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
/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
有关最佳解释,请参阅提供的答案。
为此,您需要设置另一个入口
,并将其配置为禁用基本身份验证。
你也可以在堆栈上检查这个问题和这个问题。我的实验表明,它不需要像前面的答案中提到的那样有两个入口控制器
一个Nginxingres控制器
和两个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最终成为解决方案。我已经发布了一个答案,如果你需要任何其他信息,请询问。请查看我的评论