json - Ingress-Nginx 外部身份验证的自定义响应

标签 json kubernetes nginx-ingress fastapi

我已在 EKS 上部署了 Kubernetes 集群。我有一个 ingress-nginx,它通过负载均衡器公开,以将流量路由到不同的服务。在 ingress-nginx 中,第一个请求转到 auth 服务进行身份验证,如果它是有效请求,那么我允许它继续前进。这是使用 ingress-nginx 注释 nginx.ingress.kubernetes.io/auth-url 完成的。 Auth服务是使用FastAPI开发的。如果来自 fastAPI 的 401 响应如下所示 FASTAPI

但是当我使用 ingress-nginx 时,响应看起来像这样 INGRESS_NGINX

有没有办法从 Ingress-nginx 获取 JSON 响应? 入口文件

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: 'nginx'
    nginx.ingress.kubernetes.io/use-regex: 'true'
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/auth-response-headers: item_id
    nginx.ingress.kubernetes.io/auth-method: POST
    nginx.ingress.kubernetes.io/auth-url: http://pth-auth.default.svc.cluster.local:8000/item/1
    # UPDATE THIS LINE ABOVE
spec:
  rules:
    - http:
        paths:
          - path: /?(.*)
            # UPDATE THIS LINE ABOVE
            backend:
              serviceName: client-cluster-ip-service
              servicePort: 3000
          - path: /api/?(.*)
            # UPDATE THIS LINE ABOVE
            backend:
              serviceName: server-cluster-ip-service
              servicePort: 5000
          - path: /pth-auth/?(.*)
            # UPDATE THIS LINE ABOVE
            backend:
              serviceName: pth-auth
              servicePort: 8000

最佳答案

这是一个对我有用的解决方案。它允许身份验证服务为每个请求返回自定义错误消息。

需要注意的是,由于 nginx 无法访问 auth 响应正文,因此 pth-auth 服务需要将数据放入 Pth-Auth-Error header (base64 -编码)。

此示例处理 401、500 以及 pth-auth 服务不可用时的特殊情况。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: 'nginx'
    nginx.ingress.kubernetes.io/use-regex: 'true'
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/auth-response-headers: item_id
    nginx.ingress.kubernetes.io/auth-method: POST
    nginx.ingress.kubernetes.io/auth-url: http://pth-auth.default.svc.cluster.local:8000/item/1
    # UPDATE THIS LINE ABOVE
    nginx.ingress.kubernetes.io/configuration-snippet: |
      # Redirect auth errors to custom named locations
      error_page 401 = @ingress_service_custom_error_401;
      error_page 500 = @ingress_service_custom_error_500;

      # Grab data from auth error response
      auth_request_set $pth_auth_error $upstream_http_pth_auth_error;
      auth_request_set $pth_auth_error_content_type $upstream_http_content_type;
      auth_request_set $pth_auth_status $upstream_status;

    nginx.ingress.kubernetes.io/server-snippet: |
      location @ingress_service_custom_error_401 {
        internal;

        # Decode auth response header
        set_decode_base64 $pth_auth_error_decoded $pth_auth_error;

        # Return the error from pth-auth service if any
        if ($pth_auth_error_decoded != ""){
          add_header Content-Type $pth_auth_error_content_type always;
          return 401 $pth_auth_error_decoded;
        }

        # Fall back to default nginx response
        return 401;
      }

      location @ingress_service_custom_error_500 {
        internal;

        # Decode auth response header
        set_decode_base64 $pth_auth_error_decoded $pth_auth_error;

        # Return the error from pth-auth service if any
        if ($pth_auth_error_decoded != ""){
          add_header Content-Type $pth_auth_error_content_type always;
          return 500 $pth_auth_error_decoded;
        }

        # Return a hardcoded error in case no pth-auth pods are available
        if ($pth_auth_status = 503){
          add_header Content-Type application/json always;
          return 503 "{\"msg\":\"pth-auth service is unavailable\"}";
        }

        # Fall back to default nginx response
        return 500;
      }
spec:
  rules:
    - http:
        paths:
          - path: /?(.*)
            # UPDATE THIS LINE ABOVE
            backend:
              serviceName: client-cluster-ip-service
              servicePort: 3000
          - path: /api/?(.*)
            # UPDATE THIS LINE ABOVE
            backend:
              serviceName: server-cluster-ip-service
              servicePort: 5000
          - path: /pth-auth/?(.*)
            # UPDATE THIS LINE ABOVE
            backend:
              serviceName: pth-auth
              servicePort: 8000

灵感来源:https://stackoverflow.com/a/31485557/99237

疑难解答提示:

关于json - Ingress-Nginx 外部身份验证的自定义响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65951602/

相关文章:

node.js - 如何从json文件中读取和写入数据

ruby-on-rails - 通过 RubyGems 安装 JSON 1.8.1 时出错

json - 加载 .json 文件会生成 404 错误

Kubernetes:带有 gce-proxy 的 initContainer?

kubernetes - 如何解决Google Kubernetes Engine中的 “-bash: kubeless: command not found”问题?

javascript - XML 到 JSON javascript 函数不起作用

kubernetes - kubernetes在queue_size与运行的Pod数量上自动缩放

docker - 如何在本地访问 nginx 入口?

kubernetes - 如何解决Prometheus图表Ingres/Service映射?

使用 Google Cloud Kubernetes TCP 负载均衡器的 Nginx 状态代码 499