Gateway httpsRedirect and AuthorizationPolicy prescedence with external auth

I’m using a dedicated ingress gateway with Gateway configured for port 443, httpsRedirect for port 80, and external auth with OAuth2 Proxy and Dex. When using HTTPS scheme everything works as expected, however, when trying to use HTTP, my external auth flow fails because of the absence of the CSRF header (403 Forbidden).

From my observations, it looks like the AuthorizationPolicy takes precedence over the httpsRedirect and the incoming HTTP request is redirected to OAuth2 Proxy that can’t set the required header on a non-HTTPS request.

I’m expecting the HTTP request to be redirected to HTTPS on the same host and then the AuthorizationPolicy to take the effect. Is my understanding correct here?

Here’s my configuration:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: ingress-gateway
  namespace: ingress
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
    tls:
      httpsRedirect: true
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*"
    tls:
      mode: SIMPLE
      credentialName: gateway-cert

---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
 name: auth
 namespace: auth
spec:
 hosts:
 - "*"
 gateways:
 - ingress/ingress-gateway
 http:
 - name: "dex"
   match:
   - uri:
       prefix: "/dex"
   route:
   - destination:
       host: dex.auth.svc.cluster.local
       port:
         number: 5556
 - name: "oauth2"
   match:
   - uri:
       prefix: "/oauth2"
   route:
   - destination:
       host: oauth2-proxy.auth.svc.cluster.local
       port:
         number: 80

---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: external-auth
  namespace: ingress
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: CUSTOM
  provider:
    name: oauth2-proxy
  rules:
    - to:
        - operation:
            hosts: ["*"]
            notPaths: ["/dex/*"]

Here are the results of trying to curl both HTTP and HTTPS schemes:

$> curl -v -i -k -L "https://$INGRESS_HOST/nginx/headers"
<omitted>
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
< HTTP/2 302
HTTP/2 302
content-type: text/html; charset=utf-8
location: https://192.168.50.150/dex/auth<omitted>
set-cookie: _oauth2_proxy_csrf==<omitted>



$> curl -v -i -k -L "http://$INGRESS_HOST/nginx/headers"
<omitted>
< HTTP/1.1 302 Found
HTTP/1.1 302 Found
content-type: text/html; charset=utf-8
location: https://192.168.50.150/dex/auth<omitted>
set-cookie: _oauth2_proxy_csrf=<omitted>

So it looks like in both cases the initial request is captured by the AuthorizationPolicy first prior to httpsRedirect is taking the effect.

Is it possible to redirect all HTTP traffic to HTTPS before the auth flow starts?

It looks like the AuthorizationPolicy is expected to be applied to all requests at the Gateway disregarding the redirect configuration. More details and a workaround in GitHub: External auth `AuthorizationPolicy` prevents `httpsRedirect` in `Gateway` · Issue #36498 · istio/istio · GitHub