You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Kubernetes Dashboard集成OAuth2 Proxy完成Azure AD登录后返回401如何解决?

Kubernetes Dashboard OAuth2 Proxy + Azure AD 认证异常排查

环境

  • Kubernetes Dashboard(Helm Chart 7.10.0)
  • OAuth2 Proxy(Helm Chart 7.7.28)
  • Azure Kubernetes Service(AKS)
  • Nginx Ingress Controller
  • Cert-Manager(TLS证书管理)
  • Dashboard部署在子路径/k8s-dashboard

配置清单

apiVersion: v1
kind: Namespace
metadata:
  name: kubernetes-dashboard

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kubernetes-dashboard
  labels:
    app: kubernetes-dashboard
automountServiceAccountToken: true

---
apiVersion: v1
kind: Secret
metadata:
  name: dashboard-admin-token
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/service-account.name: dashboard-admin
  labels:
    app: kubernetes-dashboard
type: kubernetes.io/service-account-token

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-admin
  labels:
    app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: dashboard-admin
    namespace: kubernetes-dashboard

---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  repo: https://kubernetes.github.io/dashboard/
  chart: kubernetes-dashboard
  version: 7.10.0
  targetNamespace: kubernetes-dashboard
  valuesContent: |-
    app:
      labels:
        app: kubernetes-dashboard
      ingress:
        enabled: true
        ingressClassName: nginx
        path: /k8s-dashboard
        hosts:
          - my-cluster.region.cloudapp.azure.com
        annotations:
          nginx.ingress.kubernetes.io/proxy-buffer-size: 64k
          nginx.ingress.kubernetes.io/backend-protocol: HTTPS
          nginx.ingress.kubernetes.io/ssl-passthrough: true
          nginx.ingress.kubernetes.io/ssl-redirect: true
          nginx.ingress.kubernetes.io/auth-url: https://$host/oauth2/auth
          nginx.ingress.kubernetes.io/auth-signin: https://$host/oauth2/start?rd=$escaped_request_uri
          nginx.ingress.kubernetes.io/auth-response-headers: Authorization,X-Auth-Request-User,X-Auth-Request-Email
        issuer:
          name: letsencrypt-prod
          scope: cluster
        tls:
          enabled: true
          secretName: tls-dashboard

---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: oauth2-proxy
  namespace: kubernetes-dashboard
spec:
  repo: https://oauth2-proxy.github.io/manifests
  chart: oauth2-proxy
  version: 7.7.28
  targetNamespace: kubernetes-dashboard
  valuesContent: |-
    ingress:
      enabled: true
      className: nginx
      path: /oauth2
      hosts:
        - my-cluster.region.cloudapp.azure.com
      tls:
        - secretName: tls-oauth-dashboard
          hosts:
            - my-cluster.region.cloudapp.azure.com
      annotations:
        nginx.ingress.kubernetes.io/proxy-buffer-size: 64k
    
    config:
      clientID: "your-client-id"
      clientSecret: "your-client-secret"
      cookieSecret: "your-cookie-secret"
      configFile: |
        provider = "azure"
        email_domains = ["*"]
        azure_tenant = "your-tenant-id"
        oidc_issuer_url = "https://login.microsoftonline.com/your-tenant-id/v2.0"
        validate_url = "https://graph.microsoft.com/v1.0/me"
        
        # Upstream configuration
        upstreams = ["file:///dev/null"]
        
        # Cookie settings
        cookie_secure = true
        cookie_domains = ["my-cluster.region.cloudapp.azure.com"]
        
        # Azure AD specific settings
        scope = "openid email profile"
        
        # Request handling
        skip_provider_button = true
        set_authorization_header = true
        set_xauthrequest = true
        
        # SSL/TLS settings
        ssl_insecure_skip_verify = true
        ssl_upstream_insecure_skip_verify = true
        
        # Auth endpoints
        whitelist_domains = ["my-cluster.region.cloudapp.azure.com"]
        redirect_url = "https://my-cluster.region.cloudapp.azure.com/oauth2/callback"
        skip_auth_routes = ["/oauth2/callback$"]

问题现象

  1. Azure AD登录流程正常完成,OAuth2 Proxy成功设置_oauth2_proxy Cookie
  2. 登录后可正确重定向至Dashboard页面
  3. Dashboard请求/me端点时返回401未授权:
{
    "ErrStatus": {
        "metadata": {},
        "status": "Failure",
        "message": "MSG_LOGIN_UNAUTHORIZED_ERROR",
        "reason": "Unauthorized",
        "code": 401
    }
}
  1. Dashboard自动跳转至令牌输入页面,即使使用kubectl -n kubernetes-dashboard create token dashboard-admin生成的有效令牌输入,仍返回401错误

排查与解决思路

1. 关闭Dashboard Ingress的ssl-passthrough注解

核心问题可能在此:启用ssl-passthrough时,Nginx Ingress会直接转发TCP流量到后端,不会解析HTTP请求头,导致auth-urlauth-response-headers等认证配置完全失效。OAuth2 Proxy的认证结果无法传递给Dashboard,因此返回401。

修改Dashboard的Ingress注解:

nginx.ingress.kubernetes.io/ssl-passthrough: false

2. 配置Dashboard启用Header认证模式

Kubernetes Dashboard默认仅支持Token认证,需显式开启Header认证以接收OAuth2 Proxy转发的用户信息。在Dashboard的Helm values中添加:

app:
  extraArgs:
    - --authentication-mode=token,header
    - --header-auth-username-header=X-Auth-Request-User
    - --header-auth-group-header=X-Auth-Request-Groups # 若需基于Azure AD组授权,需额外配置OAuth2 Proxy转发组信息

3. 配置Dashboard子路径适配

由于Dashboard部署在/k8s-dashboard子路径下,需设置base-path参数匹配Ingress路径,避免请求路径不匹配导致的认证失败:

app:
  extraArgs:
    - --base-path=/k8s-dashboard

4. 验证ServiceAccount权限与令牌有效性

手动输入令牌仍401,需确认RBAC配置与令牌权限:

  • 检查ClusterRoleBinding是否正确绑定:
kubectl describe clusterrolebinding dashboard-admin
  • 验证生成的令牌权限:
TOKEN=$(kubectl get secret dashboard-admin-token -n kubernetes-dashboard -o jsonpath='{.data.token}' | base64 -d)
kubectl auth can-i --list --token=$TOKEN

确保令牌拥有足够的集群权限。

5. 确认OAuth2 Proxy的Header转发配置

检查OAuth2 Proxy的set_authorization_headerset_xauthrequest是否为true(当前配置已设置,可在Dashboard Pod内抓包验证请求头是否包含AuthorizationX-Auth-Request-User等字段):

kubectl exec -n kubernetes-dashboard <dashboard-pod-name> -- curl -v http://localhost:9090/me -H "Authorization: Bearer <oauth2-proxy-issued-token>" -H "X-Auth-Request-User: test-user@domain.com"

6. 检查Cookie路径配置

确保OAuth2 Proxy的Cookie路径覆盖Dashboard的子路径,在OAuth2 Proxy的configFile中添加:

cookie_path = "/"

内容的提问来源于stack exchange,提问作者Mihail

火山引擎 最新活动