External Authorization not working with Istio-Ingress gateway

Deployed Istio 1.10 on the GKE cluster. The public IP of the Istio-ingress gateway is mapped with the DNS.

Expectation: Every call from Istio ingress gateway and service discovery to all APIs of microservice-A should be authenticated first and then access to that API should be allowed.

Performed below steps to integrate external authorization with microservice-A.

  1. Created external auth server using GRPC, to validate the bearer token.
  2. Updated the istio configmap to add extension provider for envoyExtAuthzGrpc.
extensionProviders:
    - name: "sample-ext-authz-grpc"
      envoyExtAuthzGrpc:
        service: "ext-authz.default.svc.cluster.local"
        port: "9000"
        includeHeadersInCheck: ["authorization"]
        headersToUpstreamOnAllow: ["authorization"]
  1. Created Authorization policy with CUSTOM action for microservice-A.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ext-authz
spec:
  selector:
    matchLabels:
      app: microservice-A
  action: CUSTOM
  provider:
      name: sample-ext-authz-grpc
  rules:
    # The rules specify when to trigger the external authorizer.
    - to:
      - operation:
          paths: ["/*"]
  1. Created Virtual service for microservice-A
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: backend-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "abc.xyz.com"
    tls:
      httpsRedirect: true
  - port:
      number: 443
      name: https-443
      protocol: HTTPS
    hosts:
    - "abc.xyz.com"
    tls:
      mode: SIMPLE # enables HTTPS on this port
      credentialName: tls-certificate-secret

---

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
spec:
  hosts:
  - "abc.xyz.com"
  gateways:
  - default/backend-gateway
  http:
  - name: microservice-A
    match:
    - uri:
        prefix: /microserviceA
    rewrite:
      uri: /
    headers:
      request:
        add:
          Cache-Control: "max-age=0, no-cache, no-store, must-revalidate"
          Pragma: "no-cache"
          Expires: "-1"
          Content-Security-Policy: "style-src 'self' https://fonts.googleapis.com/ 'unsafe-inline'"
          add_header: "more_clear_headers server"
    corsPolicy:
      allowOrigins:
      - exact: "*"
      allowMethods:
      - POST
      - GET
      allowCredentials: true
    route:
    - destination:
        host: microservice-A
        port:
          number: 9417

Problem :
Whenever we make calls to any API of microservice-A via service discovery it goes to the external auth server and validation of bearer token works and call gets forwarded to microservice-A.

CURL Request :

curl --location --request GET 'http://microservice-A:9417/books' \
--header 'Authorization: Bearer eyJhbGci'

But when we make calls to any API of microservice-A via Istio-ingress gateway it goes to the external auth server, but no headers are passed to the external auth server and the external auth server fails to validate the bearer token as it is not present in the request header.

CURL Request :

curl --location --request GET 'https://abc.xyz.com/microserviceA/books' \
--header 'Authorization: Bearer eyJhbGci'

Followed this article.
Kindly suggest a way to forward headers to the external auth server via the Istio-ingress gateway.

It seems your authorization header is just not forwarded from ingress gateway to your backend microservice-A, this does not seems like an issue in the ext-authz. Have you applied any RequestAuthentication on ingress gateway but didn’t specify the forwardOriginalToken: true in it? The
RequestAuthN could strip the Authorization header by default: Istio / JWTRule

@YangminZhu We have not applied any RequestAuthentication and we are not using JWT authentication. We are using custom authentication.

Having a similar problem. Not able to get external auth working with custom auth scheme

okay, it seems strange the header are not included when the the request is through ingress gateway, there should not be any differences here.

Could you include proxy log in ingress gateway and microservice-A with http:debug,rbac:debug,ext_authz:trace enabled (you can use istioctl pc log ... to enable the debug logging first)? I’m not sure if ingress gateway did some special operation that stripped the headers.

I got the solution. Updated the authorization policy and applied it on ingressgateway level.

Updated Authorization Policy :

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ext-authz
spec:
  selector:
    matchLabels:
      app: ingressgateway
  action: CUSTOM
  provider:
      name: sample-ext-authz-grpc
  rules:
    # The rules specify when to trigger the external authorizer.
    - to:
      - operation:
          paths: ["/microserviceA/*"]