【问题标题】:MS Azure OAuth2 proxy - Token based authentication not oauth_proxy cookieMS Azure OAuth2 代理 - 基于令牌的身份验证不是 oauth_proxy cookie
【发布时间】:2020-11-23 09:26:31
【问题描述】:

我在 Azure 中使用 Kubernetes 部署模型,有一个 OAuth2 代理 (https://github.com/oauth2-proxy/oauth2-proxy),它通过通过各种客户端启用 SSO 登录来保护集群资源。从可以使用 SSO 客户端轻松登录的最终用户的角度来看,这是可以的。当 OAuth2 代理背后的服务公开的 API 需要通过 REST 调用被外部应用程序使用时,就会出现问题。

该配置是默认配置,具有用于 OAuth2 的专用 Kubernetes 服务以及 Ingress 文件中的以下规则。

nginx.ingress.kubernetes.io/auth-signin: 'https://$host/oauth2/start?rd=$request_uri'
nginx.ingress.kubernetes.io/auth-url: 'https://$host/oauth2/auth'

根据我的检查,目前这些服务只能通过来自外部应用程序(例如 Postman)的 REST 调用来使用只有在我添加一个 cookie 参数(_oauth2_proxy ) 在使用 UI 和 SSO 客户端提供程序成功登录后生成。如果我不添加此 cookie 参数,则会出现 cookie _oauth_proxy 不存在等错误

是否有任何选项可以添加到代理配置中,以允许基于令牌的身份验证和授权/以编程方式生成某些标识符,以便通过 REST 访问技术用户(外部应用程序)的 OAuth2 代理背后的资源电话?我可以根据现有配置(客户端 ID、秘密、应用程序范围等)生成访问令牌。

OAuth2 代理部署 YAML 如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: oauth2-proxy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: oauth2-proxy
  template:
    metadata:
      labels:
        app: oauth2-proxy
    spec:
      containers:
      - env:
          - name: OAUTH2_PROXY_PROVIDER
            value: azure
          - name: OAUTH2_PROXY_AZURE_TENANT
            value: <REPLACE_WITH_DIRECTORY_ID>
          - name: OAUTH2_PROXY_CLIENT_ID
            value: <REPLACE_WITH_APPLICATION_ID>
          - name: OAUTH2_PROXY_CLIENT_SECRET
            value: <REPLACE_WITH_SECRET_KEY>
          - name: OAUTH2_PROXY_COOKIE_SECRET
            value: <REPLACE_WITH_VALUE_OF python -c 'import os,base64; print base64.b64encode(os.urandom(16))'>
          - name: OAUTH2_PROXY_HTTP_ADDRESS
            value: "0.0.0.0:4180"
          - name: OAUTH2_PROXY_UPSTREAM
            value: "<AZURE KUBERNETES CLUSTER HOST e.g.  >"
        image: bitnami/oauth2-proxy:latest
        imagePullPolicy: IfNotPresent
        name: oauth2-proxy
        ports:
        - containerPort: 4180
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
  namespace: default
spec:
  ports:
  - name: http
    port: 4180
    protocol: TCP
    targetPort: 4180
  selector:
    app: oauth2-proxy 

编辑:

我终于能够通过 AD OAuth2 令牌端点使用生成的令牌,以便在代理后面调用我的 API。为了实现这一点,我将 docker 映像从 ma​​chinedata/oauth2_proxy 更改为 bitnami/oauth2-proxy。 除此之外,我在 container 中添加了以下参数:

 args:
 - '--provider=azure'
 - '--azure-tenant=TENANT_ID'
 - '--skip-jwt-bearer-tokens=true'
 - >-
     --oidc-issuer-url=https://sts.windows.net/TENANT_ID/
 - >-
    --extra-jwt-issuers=https://login.microsoftonline.com/TENANT_ID/v2.0=APP_ID
 - '--request-logging=true'
 - '--auth-logging=true'
 - '--standard-logging=true'

此外,我必须对 Azure AD 的应用注册清单进行一些更改,以便 OAuth2 代理根据正确的版本验证令牌。

"accessTokenAcceptedVersion": 2

我也在这里找到了一些有用的解释:https://github.com/oauth2-proxy/oauth2-proxy/issues/502

现在我可以使用 Azure 提供的令牌端点为我的 API 调用生成承载令牌。唯一仍然存在的问题是我在尝试访问应用程序 UI 时遇到的错误。

在 pod 日志中收到的错误/警告是: 警告:此会话需要多个 cookie,因为它超过了 4kb cookie 限制。请改用服务器端会话存储(例如 Redis)。

浏览器收到的错误是502 Bad Gateway

编辑#2:

我能够通过增加 OAuth2 代理的入口级别的缓冲区大小来绕过这个新错误。可以在以下 URL 中找到更多详细信息。 https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider/#azure-auth-provider https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/

【问题讨论】:

  • 你得到了什么确切的错误?请提供有关环境、示例 yaml 文件等的更多详细信息。
  • 代理 pod 日志中收到的错误是:Cookie "_oauth2_proxy" 不存在。我想知道是否有可能拥有基于令牌的授权而不是 cookie 授权。我还附上了 OAuth2 代理部署的 YAML 文件。
  • 请阅读:stackoverflow.com/questions/57207365/… stackoverflow.com/questions/61148502/… 也尝试设置--cookie-secure=true。确保您重定向的 URL 在 HTTPS 上,因此 cookie 也应设置为 HTTPS。你检查了stackoverflow.com/questions/64776399/… - 你也可以添加带有cookie配置的sn-p。
  • 感谢您提供的网址。这些和其他一些帮助我走上了正确的道路。目前我只剩下一个错误,我不确定我是否可以通过配置来解决。令牌生成和使用部分现在可以正常工作。您能否告诉我您是否对我在 cmets 中添加的错误有一些见解?
  • 您能否将您的解决方案粘贴为答案而不是编辑帖子?

标签: azure kubernetes oauth-2.0 nginx-reverse-proxy


【解决方案1】:

我终于用下面的配置让它工作了:

deployment.yaml 用于 OAuth2 代理:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: oauth2-proxy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: oauth2-proxy
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: oauth2-proxy
    spec:
      containers:
        - name: oauth2-proxy
          image: 'bitnami/oauth2-proxy:latest'
          args:
            - '--provider=azure'
            - '--azure-tenant=TENANT_ID'
            - '--skip-jwt-bearer-tokens=true'
            - >-
              --oidc-issuer-url=https://sts.windows.net/TENANT_ID/
            - >-
              --extra-jwt-issuers=https://login.microsoftonline.com/TENANT_ID/v2.0=CLIENT_ID
            - '--request-logging=true'
            - '--auth-logging=true'
            - '--standard-logging=true'
          ports:
            - containerPort: 4180
              protocol: TCP
          env:
            - name: OAUTH2_PROXY_AZURE_TENANT
              value: TENANT_ID
            - name: OAUTH2_PROXY_CLIENT_ID
              value: CLIENT_ID
            - name: OAUTH2_PROXY_CLIENT_SECRET
              value: CLIENT_SECRET
            - name: OAUTH2_PROXY_COOKIE_SECRET
              value: COOKIE_SECRET
            - name: OAUTH2_PROXY_HTTP_ADDRESS
              value: '0.0.0.0:4180'
            - name: OAUTH2_PROXY_UPSTREAM
              value: 'http://your-host'
            - name: OAUTH2_PROXY_EMAIL_DOMAINS
              value: '*'

ingress.yaml 用于 OAuth2 代理:

kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: oauth2-proxy
  namespace: default
  labels:
    app: oauth2-proxy
  annotations:
    kubernetes.io/ingress.class: addon-http-application-routing
    # in my case the generated cookie was too big so I had to add the below parameters
    nginx.ingress.kubernetes.io/proxy-buffer-size: 8k
    nginx.ingress.kubernetes.io/proxy-buffers-number: '4'
spec:
  tls:
    - hosts:
        - YOUR_HOST
  rules:
    - host: YOUR_HOST
      http:
        paths:
          - path: /oauth2
            backend:
              serviceName: oauth2-proxy
              servicePort: 4180

除了这些配置文件之外,我还必须更改 Azure 应用程序注册清单中 accessTokenAcceptedVersion 的值。默认情况下,此值设置为 null,这意味着它将用于 V1 令牌,而不是 extra-jwt-issuers 参数中指定的 V2。

"accessTokenAcceptedVersion": 2

完成这些更改后,我能够通过 Azure 令牌端点使用生成的令牌,以便通过 OAuth2 代理并访问我的应用程序公开的 API:

HTTP POST to https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
Body:
  - client_id: YOUR_CLIENT_ID
  - grant_type: client_credentials
  - client_secret: YOUR_CLIENT_SECRET
  - scope: api://YOUR_CLIENT_ID/.default - this was generated by me, but it should work with MS Graph as well

【讨论】:

  • 您是否收到“会话授权无效”错误?
  • 如果令牌没有电子邮件,似乎会触发。
  • 必须删除验证 oauthproxy.go:958 中电子邮件的代码才能正常工作
【解决方案2】:

我在 Azure 中使用 Kubernetes 部署模型,它有一个 OAuth2 代理,它通过启用 SSO 登录来保护集群资源。 我的 Oauth 服务运行成功,我还部署了应用程序入口和 oauth 入口。但是当我访问应用程序 URL 时,出现 500 内部错误。如果我访问 Oauth 入口 url,我得到了登录窗口。我可以提供有关 oauth 部署 yaml 以及应用程序入口和 oauth 入口 yaml 的详细信息。

【讨论】:

    猜你喜欢
    • 2020-03-03
    • 1970-01-01
    • 2021-01-25
    • 2015-10-29
    • 2020-04-23
    • 2016-10-01
    • 2018-05-10
    • 2021-02-08
    • 2016-01-23
    相关资源
    最近更新 更多