Istio中RequestAuthentication输出的JWT头无法传入自定义AuthorizationPolicy
问题根因
- 核心原因是Istio 1.11.x版本默认的Envoy过滤器链执行顺序问题:
ext_authz(外部授权)过滤器的执行优先级高于JWT认证过滤器。你配置的my-data请求头是RequestAuthentication在JWT校验完成后才生成注入的,而调用外部授权服务的时候JWT还未完成校验,my-data头还不存在,自然无法传递给外部授权服务。 - 补充验证:你观察到
my-data可以正常送达最终业务服务,就是因为业务服务的请求是在JWT解析、外部授权都执行完成后才转发的,此时头已经生成。你替换成x-jwt-assertion能被外部授权服务收到,也符合这个逻辑——原始请求头在请求进入Envoy时就存在,不需要后续生成。
解决方案
方案1:调整过滤器执行顺序(推荐,适配Istio 1.11+版本)
你可以通过Istio的EnvoyFilter调整过滤器的执行顺序,把JWT认证过滤器放到ext_authz过滤器前面执行,步骤如下:
- 编写EnvoyFilter配置,指定JWT过滤器的运行阶段在ext_authz之前:
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: jwt-before-ext-authz namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway # 如果你是在sidecar上做的授权,这里换成sidecar对应的标签即可 configPatches: - applyTo: HTTP_FILTER match: context: GATEWAY # 对应sidecar的话填SIDECAR_INBOUND listener: portNumber: 80 # 替换成你的业务端口 filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.ext_authz" patch: operation: INSERT_BEFORE value: name: "envoy.filters.http.jwt_authn" typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication" # 这里的配置和Istio默认生成的JWT配置保持一致即可,如果你不确定可以导出现有envoy配置拷贝对应段
- 配置完成后重启对应ingressgateway/sidecar pod,此时JWT会先完成校验生成
my-data头,再执行外部授权调用,includeRequestHeadersInCheck里的my-data就可以正常传递了。
方案2:直接传递原始JWT头给外部授权服务自行解析
如果不想改过滤器顺序,你可以把原始x-jwt-assertion头加入includeRequestHeadersInCheck列表,在外部授权服务中自己实现JWT校验和payload解析即可。
方案3:升级Istio到1.12+版本
Istio 1.12版本之后官方已经优化了默认过滤器执行顺序,默认将JWT认证过滤器放在外部授权过滤器之前执行,升级后不需要额外配置即可满足需求。注意升级前做好版本兼容性测试。
内容的提问来源于stack exchange,提问作者Wasae Shoaib
相关产品推荐
相关产品推荐

