Adding headers for oauth2-proxy redirect

I’m having trouble using oauth2-proxy as an external auth with Istio 1.10.0.
My goal is configure a second Istio ingressgateway, istio-oauth-ingressgateway, and use oauth2-proxy as an extensionProvider with an AuthorizationPolicy CUSTOM action for all endpoints access through the ingressgateway.
The approach is parially explained here.

The trouble I’m having is with being redirected back to the service I’m trying to reach, after successfully authenticating via the oauth2-proxy.
It’s essentially the same problem described here.

Expected:

  • Visit bookinfo.example.com
  • Redirected to auth.example.com
  • Log in
  • Redirected to bookinfo.example.com

Actual:

  • Visit bookinfo.example.com
  • Redirected to auth.example.com
  • Log in
  • Redirected to auth.example.com
  • If I visit bookinfo.example.com again now, it will work, but I would prefer to get redirected automatically.

According to the last comment in the link above, it seems the problem might be that the ext_authz initiated request to oauth2-proxy does not contain any of the headers required by oauth2-proxy in order to redirect the request.

I’m wondering if there is a way to fix this, or if the conclusion is that oauth2-proxy is simply not fully supported yet.

Edit:

I was able to solve this by adding the following line to envoyExtAuthzHttp under meshConfig in the Istio operator config:

includeAdditionalHeadersInCheck:
  X-Auth-Request-Redirect: https://%REQ(Host)%

This effectively adds an addition header to the request sent to oauth2-proxy, where the value is extracted from the Host header.

Config:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: installation
  namespace: istio-system
spec:
  components:
    ingressGateways:
      - enabled: true
        name: istio-ingressgateway
      - enabled: true
        k8s:
          podAnnotations:
            proxy.istio.io/config: '{"gatewayTopology": { "numTrustedProxies": 2 }}'
        label:
          app: istio-oauth-ingressgateway
          istio: oauth-ingressgateway
        name: istio-oauth-ingressgateway
    pilot:
      enabled: true
  meshConfig:
    extensionProviders:
      - envoyExtAuthzHttp:
          port: 4180
          service: oauth2-proxy.istio-system.svc.cluster.local
          headersToDownstreamOnDeny:
            - content-type
            - set-cookie
          headersToUpstreamOnAllow:
            - authorization
            - cookie
            - path
          includeHeadersInCheck:
            - "cookie"
            - "x-forwarded-access-token"
            - "x-forwarded-user"
            - "x-forwarded-email"
            - "authorization"
            - "x-forwarded-proto"
            - "proxy-authorization"
            - "user-agent"
            - "x-forwarded-host"
            - "from"
            - "x-forwarded-for"
            - "x-forwarded-uri"
            - "x-auth-request-redirect"
            - "accept"
        name: oauth2-proxy
  namespace: istio-system
  profile: default
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  labels:
    argocd.argoproj.io/instance: oauth2-proxy
  name: oauth-ingressgateway
  namespace: istio-system
spec:
  action: CUSTOM
  provider:
    name: oauth2-proxy
  rules:
    - to:
        - operation:
            paths:
              - '*'
  selector:
    matchLabels:
      istio: oauth-ingressgateway
apiVersion: apps/v1
kind: Deployment
metadata:
  name: oauth2-proxy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: oauth2-proxy
  template:
    metadata:
      labels:
        app: oauth2-proxy
        istio-injection: enabled
    spec:
      containers:
        - args:
            - '--provider=github'
            - '--client-id=<client-id>'
            - '--client-secret=<client-secret>'
            - '--http-address=0.0.0.0:4180'
            - '--email-domain=*'
            - '--cookie-refresh=1h'
            - '--cookie-secure=false'
            - '--set-xauthrequest'
            - '--pass-access-token'
            - '--set-authorization-header'
            - '--upstream="static://200"'
            - '--skip-provider-button=true'
            - '--reverse-proxy'
          env:
            - name: OAUTH2_PROXY_WHITELIST_DOMAINS
              value: .example.com
            - name: OAUTH2_PROXY_COOKIE_DOMAINS
              value: .example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: oauth2-proxy-gw
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - auth.example.com
      port:
        name: http
        number: 80
        protocol: HTTP
      tls:
        httpsRedirect: true
    - hosts:
        - auth.example.com
      port:
        name: https
        number: 443
        protocol: HTTPS
      tls:
        credentialName: <cert>
        mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: oauth2-proxy-vs
  namespace: istio-system
spec:
  gateways:
    - oauth2-proxy-gw
  hosts:
    - auth.example.com
  http:
    - route:
        - destination:
            host: oauth2-proxy.istio-system.svc.cluster.local
            port:
              number: 4180
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gw
  namespace: default
spec:
  selector:
    istio: oauth-ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
      - bookinfo.example.com
      tls:
        httpsRedirect: true
    - port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: SIMPLE
        credentialName: <cert>
      hosts:
      - bookinfo.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo-vs
  namespace: default
spec:
  hosts:
    - bookinfo.example.com
  gateways:
    - bookinfo-gw
  http:
    - route:
      - destination:
          host: productpage.default.svc.cluster.local
          port:
            number: 9080

hi @djfinnoy
That’s exactly what I’m looking for. Setting the includeAdditionalHeadersInCheck to recommended value doesn’t seem to work on my side. Do you know maybe if something has changed since your last post?

edit: it works now! Seems istio didn’t apply the changes properly.

Another question - where did you find the specification of which variables are supported in that redirect? I’m initiating the url from multiple urls, i.e. https://%REQ(Host)%/ui & https://%REQ(Host)%/report. Is it possible to get the whole URL path in there?

edit: found the solution: https://%REQ(Host)%/%REQ(:PATH)%

These are envoy parameters, i.e. Access logging — envoy 1.22.0-dev-ed48fa documentation (envoyproxy.io)

Hey guys, thank you very much wouldn’t figure out without you!

This setup should be added here: Overview | OAuth2 Proxy

How would I go about checking that the headers included in includeAdditionalHeadersInCheck are in the request? When checking the istio logs for oauth2-proxy I don’t see my add’l header coming across.

Istio v1.9.6
OAuth2-Proxy v7.3.0