External Autz: invalid redirect uri with Oauth2 proxy

I have am having some troubles getting outh2-proxy to work with Istio. Specifically, oauth2 correctly talk to Keycloak, but when I try to access https://stage.property.xyz, the redirect URI becomes redirect_uri=https%3A%2F%2F10.0.2.184%3A8012%, which it is the internal envoy ip not routable from the outside.

Let me give the context:

Istio-operator:

 extensionProviders:
    - name: "ext-authz-service"
      envoyExtAuthzHttp:
        service: "oauth2proxy.auth.svc.cluster.local"
        port: 4180
        includeHeadersInCheck: ["authorization", "cookie"] # headers sent to the oauth2-proxy in the check request.
        headersToUpstreamOnAllow: ["authorization", "path", "x-auth-request-user", "x-auth-request-email", "x-auth-request-access-token"] # headers sent to backend application when request is allowed.
        headersToDownstreamOnDeny: ["content-type", "set-cookie"] # headers sent back to the client when request is denied.

Service entry:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: oauth2
spec:
  hosts:
    - oauth2proxy.auth.svc.cluster.local
  ports:
    - number: 4180
      name: http
      protocol: HTTP
  resolution: STATIC

Authorization policy

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ext-authz
spec:
  selector:
    matchLabels:
      service.istio.io/canonical-name: platform-frontend
  action: CUSTOM
  provider:
    name: "ext-authz-service"
  rules:
  - to:
    - operation:
        paths: ["/"]

Oauth2 deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: oauth2proxy
  name: oauth2proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: oauth2proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2proxy
    spec:
      containers:
        - image: quay.io/oauth2-proxy/oauth2-proxy:v7.1.3
          imagePullPolicy: Always
          name: oauth2-proxy
          ports:
          - containerPort: 4180
            protocol: TCP
          env:
          - name: KEYCLOAK_CLIENT_ID
            valueFrom:
              secretKeyRef:
                name: keycloak-client-secret-platform-frontend-client
                key: CLIENT_ID
          - name: KEYCLOAK_CLIENT_SECRET
            valueFrom:
              secretKeyRef:
                name: keycloak-client-secret-platform-frontend-client
                key: CLIENT_SECRET
          - name: COOKIE_SECRET
            valueFrom:
              secretKeyRef:
                name: oauth2proxy
                key: cookieSecret
          - name: REDIS_PASSWORD
            valueFrom:
              secretKeyRef:
                name: auth-redis
                key: redis-password
          args:
          - --provider=oidc
          - --provider-display-name="Keycloak"
          - --client-id=$(KEYCLOAK_CLIENT_ID)
          - --client-secret=$(KEYCLOAK_CLIENT_SECRET)
          - --email-domain="*"
          - --pass-access-token=true
          - --pass-authorization-header=true
          - --set-authorization-header=true
          - --oidc-issuer-url=https://auth.{{ .Values.jxRequirements.ingress.domain }}/auth/realms/engineering-realm
          - --login-url=https://auth.{{ .Values.jxRequirements.ingress.domain }}/auth/realms/engineering-realm/protocol/openid-connect/auth
          - --redeem-url=https://auth.{{ .Values.jxRequirements.ingress.domain }}/auth/realms/engineering-realm/protocol/openid-connect/token
          - --validate-url=https://auth.{{ .Values.jxRequirements.ingress.domain }}/auth/realms/engineering-realm/protocol/openid-connect/userinfo
          - --http-address=http://:4180
          - --scope=openid profile email roles
          - --cookie-refresh=4m0s
          - --cookie-expire=4h0m0s
          - --cookie-secure=true
          - --cookie-secret=$(COOKIE_SECRET)
          - --whitelist-domain={{ .Values.jxRequirements.ingress.domain }}
          - --cookie-domain=.{{ .Values.jxRequirements.ingress.domain }}
          - --standard-logging=true
          - --auth-logging=true
          - --request-logging=true
          - --skip-provider-button=true
          - --upstream=static://200
          - --redis-connection-url=redis://auth-redis-master.auth.svc.cluster.local:6379
          - --redis-password=$(REDIS_PASSWORD)
          - --session-store-type=redis

Finally, I am deploying a KService, which is not public (it has url http://platform-frontend.jx-staging.svc.cluster.local), but I have create the following to make it public accessible (and to give it the fqdn):

apiVersion: serving.knative.dev/v1alpha1
kind: DomainMapping
metadata:
  name: {{ .Values.jxRequirements.ingress.domain }}
spec:
  ref:
    name: platform-frontend
    kind: Service
    apiVersion: serving.knative.dev/v1

Thanks in advance for any help.

Setting this parameter to X-Forwarded-For in oauth2-proxy solved the problem.

--real-client-ip-header | string | Header used to determine the real IP of the client, requires --reverse-proxy to be set (one of: X-Forwarded-For, X-Real-IP, or X-ProxyUser-IP)
-- | -- | --

Hope this could be useful for someone in the same situation.

1 Like

Discussion on Slack Slack