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

时间:2020-09-24 05:23:23

标签: 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中解决基于路径的路由方面的任何帮助。

1 个答案:

答案 0 :(得分:2)

尝试将--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和密码(已设置openshift-service-account,从/var/run/secrets/kubernetes.io/serviceaccount/中读取那些令牌)从Oauth门户请求令牌。如果无法进行检测,则可以改用client-id=system:serviceaccount:$ns:$saclient-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token
  • Oauth SP使用serviceaccounts.openshift.io/oauth-redirectreference annotation检查我们的ServiceAccount(尽管还有另一种方法,我不太熟悉的是OauthClient),以匹配客户端请求的应用程序URL。成功匹配后,SP会使用一些临时令牌回复oauth-proxy
  • 知道了令牌和proxy-prefix之后,oauth-proxy会将未经身份验证的用户重定向到Oauth登录门户,并使用一些编码的回调URL作为GET参数
  • 用户针对OpenShift用户群登录
  • 成功登录后,Oauth门户会使用从代理接收到的回调URL将您重定向到oauth-proxy
  • oauth-proxy兑换其令牌
  • 如果定义了openshift-sar,则oauth-proxy会进行一些其他检查,以确保客户端得到授权,否则任何用户都可以登录
  • 用户可以选择同意授予某些权限

在OpenShift上下文中,初始令牌请求是使用login-url参数完成的,该参数默认为kubernetes.default.svc/oauth/authorize,尽管在某些情况下(不确定,某些异常的网络策略),您可能想要强制改为使用您的OpenShift控制台FQDN。

通过redeem-url(默认为kubernetes.default.svc/oauth/token)进行令牌兑换。同样,如果SDN否则拒绝此流量,则可以在此处使用公共控制台FQDN。

所以,代理前缀是如何出现的:仅当您的oauth-proxy构建正确的回调URL时才需要,登录表单会将您发送回正确的子路径您的应用程序。

并且OAuthRedirectReference主要由OpenShift使用,以确保请求令牌的客户端确实旨在对给定Route进行身份验证的客户端。对于您而言,仅匹配FQDN,尽管我认为除了serviceaccounts.openshift.io/oauth-redirectreference.$name: {"kind": ...}之外,您还可以设置类似serviceaccounts.openshift.io/oauth-redirecturi.name: my-path