一 现象
spring webflux通过spring-cloud-gateway转发或者不通过网关转发都可正常访问,但是通过zuul网关这出现400错误的请求。
二 配置
zuul配置如下,其中url是k8s的service,转发到的应用是spring webflux应用1
2
3
4
5
6
7
8zuul:
routes:
coupon-service-v2:
path: /coupon/**
url: http://coupon-service-v2:8080/api
sensitiveHeaders:
customSensitiveHeaders: true
addHostHeader: true
三 通过日志看到以下的请求头
x-forwarded-xxx 的三个请求头都是多值的
而当请求的 X-Forwarded-Host 值零个或一个时,请求返回 200。X-Forwarded-Host 值大于一个时,请求返回 400。
Host与X-Forwarded-Host一样,难道 X-Forwarded-Host 的值会被复制到 Host 吗?
答案是肯定的,请参考https://github.com/kubernetes/ingress-nginx/issues/2463
https://github.com/kubernetes/ingress-nginx/issues/3790
原来 Ingress 在开启 use-forwarded-headers 后,会将 X-Forwarded-Host 的值复制到 Host,但由于没有考虑 X-Forwarded-Host 为多个值的情况,导致 Host 不合法。这个问题已经在 ingress-nginx 0.24 版本被修复。
1 | x-request-id:bbd6fb1cd4eef27d3f57e9a10118795e |
四 解决方案
- 升级
ingress-nginx
至 0.24 及以上版本,从根本上解决这个问题。 - 配置
zuul.addProxyHeaders = false
,使得 Zuul 不添加额外的X-Forwarded-Host
。