连接到 Azure B2C 时如何调试 oauth2_proxy? [英] How can I debug oauth2_proxy when connecting to Azure B2C?

查看:93
本文介绍了连接到 Azure B2C 时如何调试 oauth2_proxy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Kubernetes 的新手,我一直在学习 Ingress.在 Ingress 处处理 TLS 证书和身份验证的想法给我留下了深刻的印象.我添加了一个简单的静态文件服务器,并添加了cert-manager,所以我基本上有一个HTTPS静态网站.

I'm new to Kubernetes, and I've been learning about Ingress. I'm quite impressed by the idea of handling TLS certificates and authentication at the point of Ingress. I've added a simple static file server, and added cert-manager, so I basically have a HTTPS static website.

我读到 NGINX 入口控制器可以与 oauth2 代理一起使用来处理入口处的身份验证.问题是我根本无法做到这一点.我可以确认我的 oauth2-proxy 部署服务和部署存在且正确 - 在 Pod 的日志中,我可以看到来自 NGINX 的请求,但我看不到它在 Azure B2C 上实际调用的 uri.每当我尝试访问我的服务时,我都会收到 500 内部错误 - 如果我将/oath2/auth 地址放在浏览器中,我会收到不支持请求中指定的范围‘openid’.".但是,如果我在 Azure 中测试运行用户流,则测试 URL 还会指定openid"并且它按预期运行.

I read that NGINX Ingress Controller can be used with oauth2 proxy to handle authentication at the ingress. The problem is that I can't get this working at all. I can confirm that my oauth2-proxy Deployment Service and Deployment are present and correct - in the Pod's log, I can see the requests coming through from NGINX, but I can't see what uri it is actually calling at Azure B2C. Whenever I try and access my service I get a 500 Internal error - if I put my /oath2/auth address in the browser, I get "The scope 'openid' specified in the request is not supported.". However if I Test run the user Flow in Azure, the test URL also specifies "openid" and it functions as expected.

如果我能找出如何监控来自 Azure 的 oauth2-proxy 请求(即通过观察它的 uri 找出我的配置错误的地方),我认为我可以解决这个问题 - 否则,也许已经这样做的人可以告诉我我在配置中哪里出错了.

I think that I could work through this if I could find out how to monitor what oauth2-proxy requests from Azure (i.e. work out where my config is wrong by observing it's uri) - otherwise, maybe somebody that has done this can tell me where I went wrong in the config.

我的配置如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: oauth2-proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2-proxy
    spec:
      containers:
      - args:
        - -provider=oidc
        - -email-domain=*
        - -upstream=file:///dev/null
        - -http-address=0.0.0.0:4180
        - -redirect-url=https://jwt.ms/
        - -oidc-issuer-url=https://<tenant>.b2clogin.com/tfp/<app-guid>/b2c_1_manager_signup/
        - -cookie-secure=true
        - -scope="openid"

        # Register a new application
        # https://github.com/settings/applications/new
        env:
        - name: OAUTH2_PROXY_CLIENT_ID
          value: <app-guid>
        - name: OAUTH2_PROXY_CLIENT_SECRET
          value: <key-base64>
        - name: OAUTH2_PROXY_COOKIE_SECRET
          value: <random+base64>
        image: quay.io/pusher/oauth2_proxy:latest
        imagePullPolicy: Always
        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:
    k8s-app: oauth2-proxy
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: static1-oauth2-proxy
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: cloud.<mydomain>
    http:
      paths:
      - backend:
          serviceName: oauth2-proxy
          servicePort: 4180
        path: /oauth2
  tls:
  - hosts:
    - cloud.<mydomain>
    secretName: cloud-demo-crt

在我的静态站点入口中,我将以下内容添加到 metadata.annotations:

In my static site ingress I have the following added to metadata.annotations:

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

我不是 100% 确定这些注释是否应该始终如此设置,或者我是否应该为 B2C/OIDC 更改这些注释,但它们似乎转到了代理,这正是代理接下来要做的失败.

I'm not 100% sure whether these annotations should always be set as such, or whether I should have varies these for B2C/OIDC, but they seem to go off to the proxy, it's just what the proxy does next that fails.

请注意,日志确实表明 oauth2-proxy 已连接到 B2C,实际上,如果颁发者 uri 更改,则会进入崩溃回退循环.

Note that the log does indicate that oauth2-proxy connected to B2C, indeed if the issuer uri changes, then it goes into a crash fallback loop.

似乎有很多关于如何设置的文章,所以我确定这是可能的,但我有点迷失了.如果有人可以帮助设置或调试想法,那就太好了.

There seem to be anumber of articles about how to set this up, so I'm sure it's possible, but I got a little lost. If somebody could help with the setup or ideas for debugging, that would be wonderful.

谢谢.

现在我能够可靠地获得 ?state= 和 code= 以显示在/oauth2/callback 页面的浏览器窗口中,但该页面报告内部错误.oauth2_proxy 现在应该记录日志,并且日志显示:

Now I'm able to reliably get a ?state= and code= to display in the browser window on the /oauth2/callback page, but the page reports Internal Error. oauth2_proxy is logging when it should now, and the log says:

[2020/06/03 21:18:07] [oauthproxy.go:803] 在 OAuth2 回调期间兑换代码时出错:令牌交换:oauth2:服务器响应缺少 access_token

[2020/06/03 21:18:07] [oauthproxy.go:803] Error redeeming code during OAuth2 callback: token exchange: oauth2: server response missing access_token

我的 Azure B2C 审计日志显示它正在发布 id_tokens.

My Azure B2C Audit log howwever says that it is issuing id_tokens.

当我查看 oauth2_proxy 的源代码时,问题似乎发生在 oauth2.config.Exchange() 期间 - 它位于 goloang 库中 - 我不知道那是做什么的,但我不知道认为它与 Azure B2c 一起工作正常.有人知道我如何从这里取得进展吗?

When I look at the source code to oauth2_proxy, it looks as though the problem occurs during oauth2.config.Exchange() - which is in the goloang library - I don't know what that does, but I don't think that it works properly with Azure B2c. Does anybody have an idea how I can progress from here?

谢谢.

标记

推荐答案

我求助于在 VSCode 中编译和调试代理应用程序.我运行了一个简单的 NGINX 代理来为代理提供 TLS 终止,以允许 Azure B2C 端运行.事实证明,我做错了很多事情.以下是我解决的问题列表,希望其他人能够使用它通过 Azure B2C 运行他们自己的 oauth_proxy.

I resorted to compiling and debugging the proxy app in VSCode. I ran a simple NGINX proxy to supply TLS termination to the proxy to allow the Azure B2C side to function. It turns out that I had got a lot of things wrong. Here are a list of problems that I resolved in the hope that somebody else might be able to use this to run their own oauth_proxy with Azure B2C.

当附加到调试器时,很明显 oauth2_proxy 读取令牌并期望 fin,依次是 access_token,然后是 id_token,然后它需要(默认情况下)电子邮件"索赔.

When attached to a debugger, it is clear that oauth2_proxy reads the token and expects to fin, in turn access_token, then id_token, it then requires (by default) the "email" claim.

获取access_token"要返回,您必须请求访问某些资源.最初我没有这个.在我的 yaml 文件中,我有:

To get an "access_token" to return, you have to request access to some resource. Initially I didn't have this. In my yaml file I had:

    - --scope=openid

注意:不要在 YAML 中为范围值加上引号,因为它们被视为请求范围值的一部分!

Note: do not put quotation marks around your scope value in YAML, because they are treaded as a part of the requested scope value!

我必须设置一个阅读"通过应用注册"在 Azure B2C 中的范围和公开 API".我最终起作用的范围是以下形式:

I had to set up a "read" scope in Azure B2C via "App Registrations" and "Expose an API". My final scope that worked was of the form:

    - --scope=https://<myspacename>.onmicrosoft.com/<myapiname>/read openid

你必须确保两个作用域(read 和 openid)一起通过,否则你不会得到一个 id_token.如果您收到错误消息,指出您在服务器响应中没有 id_token,请确保在一次使用 --scope 标志时通过这两个值.

You have to make sure that both scopes (read and openid) go through together, otherwise you don't get an id_token. If you get an error saying that you don't have an id_token in the server response, make sure that both values are going through in a single use of the --scope flag.

一旦您拥有 access_token 和 id_token,oauth2_proxy 就会失败,因为没有电子邮件";宣称.Azure B2C 有一个电子邮件"声称,但我认为不能使用.为了解决这个问题,我使用了对象 ID,我设置了:

Once you have access_token and id_token, oauth2_proxy fails because there is no "email" claim. Azure B2C has an "emails" claim, but I don't think that can be used. To get around this, I used the object id instead, I set:

    - --user-id-claim=oid

我遇到的最后一个问题是浏览器中没有设置 cookie.我确实看到 oauth2-proxy 输出中 cookie 值本身太长的错误,我删除了offline_access"范围和该消息消失了.然而,浏览器中仍然没有 cookie.

The last problem I had was that no cookies were being set in the browser. I did see an error that the cookie value itself was too long in the oauth2-proxy output, and I removed the "offline_access" scope and that message went away. There were still not cookies in the browser however.

然而,我的 NGinX 入口日志确实有一条消息,表明标头超过 8K,因此 NGinX 报告了 503 错误.

My NGinX ingress log did however have a message that the Headers were more than 8K, and NGinX was reporting a 503 error because of this.

在 oauth2-proxy 文档中,有一个描述,如果您的 cookie 很长,则应使用 Redis 存储 - 它专门将 Azure AD cookie 标识为足够长以保证 Redis 解决方案.

In the oauth2-proxy documents, there is a description that a Redis store should be used if your cookie is long - it specifically identifies Azure AD cookies as being long enough to warrant a Redis solution.

我安装了一个单节点 Redis 以使用此答案中的 YAML 配置进行测试(未强化)https://stackoverflow.com/a/53052122/2048821 - 必须使用 --session-store-type=redis 和 --redis-connection-url 选项.

I installed a single node Redis to test (unhardened) using a YAML config from this answer https://stackoverflow.com/a/53052122/2048821 - The --session-store-type=redis and --redis-connection-url options must be used.

我的 oauth2_proxy 的最终服务/部署如下所示:

The final Service/Deployment for my oauth2_proxy look like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: oauth2-proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2-proxy
    spec:
      containers:
      - args:
        - --provider=oidc
        - --email-domain=*
        - --upstream=file:///dev/null
        - --http-address=0.0.0.0:4180
        - --redirect-url=https://<myhost>/oauth2/callback
        - --oidc-issuer-url=https://<mynamespane>.b2clogin.com/tfp/<my-tenant>/b2c_1_signin/v2.0/
        - --cookie-secure=true
        - --cookie-domain=<myhost>
        - --cookie-secret=<mycookiesecret>
        - --user-id-claim=oid
        - --scope=https://<mynamespace>.onmicrosoft.com/<myappname>/read openid
        - --reverse-proxy=true
        - --skip-provider-button=true
        - --client-id=<myappid>
        - --client-secret=<myclientsecret>
        - --session-store-type=redis
        - --redis-connection-url=redis://redis:6379

        # Register a new application
        image: quay.io/pusher/oauth2_proxy:latest
        imagePullPolicy: Always
        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:
    k8s-app: oauth2-proxy

希望这可以为某人节省大量时间.

Hope that this saves somebody a lot of time.

标记

这篇关于连接到 Azure B2C 时如何调试 oauth2_proxy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆