docker - 在 Openshift 上保护基于路径的路由

标签 docker kubernetes oauth-2.0 openshift kubernetes-ingress

我在 openshift 上部署的应用程序的 url 为 https://host:port/app/v1/hello/
我使用 ServiceAccount 作为 Oauth 客户端,并且提供者是 Openshift,所以我应该被重定向到 Openshift 登录页面进行授权。
我们已经配置了 openshift/oauth-proxy,效果很好。
https://github.com/openshift/oauth-proxy/
现在我们进一步要求基于路径的路由,例如如果 URL 有/app/v1 然后重定向到 Service1,如果/app/v2 然后重定向到 Service2
这是我的配置的工作示例,

`kind: Template
apiVersion: v1
metadata:
  name: deployment-template
objects:
  - apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: my-service-account
      annotations:
        serviceaccounts.openshift.io/oauth-redirectreference.first: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"my-route"}}'
  - apiVersion: v1
    kind: Service
    metadata:
      name: my-service
      annotations:
        service.alpha.openshift.io/serving-cert-secret-name: proxy-tls
    spec:
      selector:
        app: spring-boot-docker-openshift-hello-world
      ports:
        - name: api
          protocol: TCP
          port: 443 #Port the service listens on.
          targetPort: 8443 #Port on the backing pods to which the service forwards connections.
  - apiVersion: v1
    kind: Route
    metadata:
      name: my-route
    spec:
      port:
        targetPort: api
      path: "/"
      to:
        kind: Service
        name: my-service
      tls:
        termination: Reencrypt
  - apiVersion: apps.openshift.io/v1
    kind: DeploymentConfig
    metadata:
      labels:
        app: spring-boot-docker-openshift-hello-world
        version: 0.0.1-SNAPSHOT.1.dev
      name: spring-boot-docker-openshift-hello-world
    spec:
      replicas: 1
      selector:
        app: spring-boot-docker-openshift-hello-world
      strategy:
        rollingParams:
          timeoutSeconds: 3600
        type: Rolling
      template:
        metadata:
          labels:
            app: spring-boot-docker-openshift-hello-world
            version: 0.0.1-SNAPSHOT.1.dev
        spec:
          serviceAccount: my-service-account
          serviceAccountName: my-service-account
          containers:
          - name: spring-boot-docker-openshift-hello-world
            env:
              - name: KUBERNETES_NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
            image: pokarjm/spring-boot-docker-openshift-hello-world:0.0.1-SNAPSHOT.1.dev
            imagePullPolicy: IfNotPresent
            securityContext:
              privileged: false
            ports:
              - containerPort: 8080
                protocol: TCP
          - name: oauth-proxy
            image: openshift/oauth-proxy:latest
            imagePullPolicy: IfNotPresent
            ports:
              - containerPort: 8443
                name: public
            args:
              - --https-address=:8443
              - --provider=openshift
              - --openshift-service-account=my-service-account
              - --upstream=http://localhost:8080
              - --tls-cert=/etc/tls/private/tls.crt
              - --tls-key=/etc/tls/private/tls.key
              - --cookie-secret-file=/etc/proxy/secret/session_secret
              - --openshift-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
              - --openshift-sar={"namespace":"spring-boot-docker-openshift-hello-world","resource":"services","name":"my-service","verb":"get"}
              - --request-logging=true
            volumeMounts:
              - mountPath: /etc/tls/private
                name: proxy-tls
                readOnly: true
              - mountPath: /etc/proxy/secret
                name: oauth-proxy-secret
                readOnly: true
          volumes:
            - name: proxy-tls
              secret:
                defaultMode: 420
                secretName: proxy-tls
            - name: oauth-proxy-secret
              secret:
                defaultMode: 420
                secretName: oauth-proxy-secret
      triggers:
        - type: ConfigChange
`
现在为了支持基于路径的路由,即将请求/app/v1 映射到 Service1,我只是在路由中添加了路径,如下所示,
- apiVersion: v1
    kind: Route
    metadata:
      name: my-route
    spec:
      port:
        targetPort: api
      path: "/app/v1"
      to:
        kind: Service
        name: my-service
      tls:
        termination: Reencrypt
但是通过这些更改,我可以看到如下所示的初始登录页面
image
但是在单击上面的按钮而不是获取 openshift 登录页面后,我在下面看到,
image
如果我将路径中的路径更改为路径:“/”它可以工作并显示登录屏幕。
感谢有关修复 openshift/oauth-proxy 中基于路径的路由的任何帮助。

最佳答案

尝试添加类似 --proxy-prefix=/app/v1 的内容, 到您的 oauth 代理容器。
例如:

[...]
        args:
          - --https-address=:8443
          - --provider=openshift
          - --proxy-prefix=/app/v1
          - --openshift-service-account=my-service-account
[...]
否则,oauth-proxy 将假定它正在服务的应用程序位于您的 Route 的根目录,从而中断登录回调重定向。

现在,关于您在评论中提出的问题,我不确定我自己是否得到了这一切,我没有一个 OpenShift 集群来测试它,...... 加点盐,欢迎编辑,如果有人能得到这个权利。
据我了解和记忆:
  • 客户端通过您的 oauth-proxy 连接到您的应用程序。
  • 代理看到您的客户端未经身份验证,并使用其客户端 ID 和 secret (已设置 openshift-service-account ,从 /var/run/secrets/kubernetes.io/serviceaccount/ 中读取)从 Oauth 门户请求 token 。您可以改用 client-id=system:serviceaccount:$ns:$saclient-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token ,如果检测以某种方式不起作用。
  • Oauth SP 使用 serviceaccounts.openshift.io/oauth-redirectreference 检查我们的 ServiceAccount。 annotation (尽管还有另一种方法可以做到这一点,我不太熟悉 OauthClient),匹配客户端请求的应用程序 URL。成功匹配后,SP 使用一些临时 token
  • 回复 oauth-proxy
  • 知道那个 token 和 proxy-prefix ,oauth-proxy 将未经身份验证的用户重定向到 Oauth 登录门户,并使用一些编码的回调 URL 作为 GET 参数
  • 用户登录 OpenShift 用户群
  • 成功登录后,Oauth 门户使用从您的代理接收到的回调 URL
  • 将您重定向到 oauth-proxy
  • oauth-proxy 赎回其 token
  • 如果 openshift-sar被定义后,oauth-proxy 会进行一些额外的检查以确保客户端被授权,否则任何用户都可以登录
  • 用户可选择同意授予某些权限

  • 在 OpenShift 上下文中,初始 token 请求是使用 login-url 完成的。参数,默认为 kubernetes.default.svc/oauth/authorize ,尽管在某些情况下(不确定是否记得,一些不寻常的网络策略),您可能希望强制使用您的 OpenShift 控制台 FQDN。
    代币兑换通过 redeem-url 完成。默认为 kubernetes.default.svc/oauth/token .同样,如果 SDN 拒绝此流量,您可以在此处使用您的公共(public)控制台 FQDN。

    那么,proxy-prefix 是如何出现的:只需要您的 oauth-proxy 构建正确的回调 URL,登录表单才能将您发送回应用程序的正确子路径。
    OAuthRedirectReference 主要由 OpenShift 使用,以确保请求 token 的客户端确实是针对给定路由的经过身份验证的客户端。在你的情况下,只匹配一个 FQDN,虽然我认为除了 serviceaccounts.openshift.io/oauth-redirectreference.$name: {"kind": ...} , 你也可以设置 serviceaccounts.openshift.io/oauth-redirecturi.name: my-path

    关于docker - 在 Openshift 上保护基于路径的路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64040017/

    相关文章:

    java - 如何使用 Java 命令行应用程序对 https ://tfspreview. com(MIcrosoft 托管的 TFS)进行身份验证?

    mongodb - docker:创建一个在 docker-compose down 之后仍然保存的 mongodb 卷?

    python - 从Google Cloud Run执行记录的最简单方法

    linux - 无法在 docker Alpine 中添加具有高 UID 的用户

    node.js - 由于同意屏幕,无法创建 Google oAuth 客户端 ID

    android - AccountManagerFuture.getResults 抛出 IOException,而连接处于 Activity 状态

    docker - 无法在 Docker for Windows 上访问 RabbitMQ

    kubernetes - 将kubelet指向连接的磁盘

    kubernetes - Terraform:使用一个应用启动 GKE 集群和 Ingress 应用程序

    azure - 当 Pod 重新创建时,Prometheus 发生崩溃循环