Vert.x WebClient发起HTTPS请求返回403 Forbidden问题咨询
问题背景
在AWS上配置了启用IP白名单访问控制的HTTPS站点,本地设备通过已加入白名单的VPN连接网络时,使用浏览器、JDK原生java.net.http.HttpClient编写的代码均可正常访问站点,对应可正常访问的实现代码如下:
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://mywebsite/route")) .GET() // GET is default .build(); HttpResponse<Void> response = client.send(request, HttpResponse.BodyHandlers.discarding());
将访问逻辑替换为io.vertx.ext.web.client包提供的Vert.x WebClient实现后,访问同一站点会收到403 Forbidden响应,对应实现代码如下:
WebClientOptions options = new WebClientOptions().setTryUseCompression(true).setTrustAll(true); HttpRequest<Buffer> request = WebClient.create(vertx, options) .getAbs("https://mywebsite/route") .ssl(true).putHeaders(headers); request.send(asyncResult -> { if (asyncResult.succeeded()) { HttpResponse response = asyncResult.result(); } });
问题原因排查
同网络环境下常规客户端可正常访问,仅Vert.x实现返回403,问题全部来自Vert.x客户端默认配置和常规HTTP客户端的行为差异,按出现概率排序如下:
- 出口流量未走VPN通道,源IP不在白名单内
这是占比最高的诱因:JDK原生HttpClient、浏览器默认会自动读取系统代理配置、路由表规则,VPN连接后下发的路由转发、代理规则会自动生效,请求从VPN的白名单出口IP访问目标站点。但Vert.x WebClient默认不加载系统代理配置,也不会自动优先匹配VPN路由:- 如果VPN是代理模式,Vert.x默认直连目标站点,源IP是本地公网出口IP,直接触发IP白名单拦截
- 如果VPN是全局路由模式,Vert.x客户端创建时未指定本地绑定地址的话,可能优先绑定物理网卡出口,流量绕过VPN隧道直接发往公网
- 请求头特征触发AWS侧防护规则拦截
代码中显式调用putHeaders(headers)传入自定义请求头,同时Vert.x默认请求头和常规客户端存在明显差异:- Vert.x WebClient默认User-Agent为
Vert.x-WebClient/<version>,不属于常见浏览器、标准HTTP客户端UA标识,若AWS侧配置了WAF Bot管控、自定义UA拦截规则,会直接返回403 - 自定义请求头若存在缺失、冲突(比如重复传Host头、Origin/Referer值不符合站点跨域规则、缺少服务端强制校验的特定头),会直接触发访问拦截
- 开启
setTryUseCompression(true)后,客户端会自动携带Accept-Encoding: gzip, deflate头,若服务端WAF对压缩请求有特殊校验规则,也可能返回403
排查时可直接抓包对比正常可通请求和Vert.x请求的全量请求头,完全对齐后再测试即可定位这类问题。
- Vert.x WebClient默认User-Agent为
- HTTPS握手配置异常导致请求落到错误的服务端节点
代码中setTrustAll(true)配置仅代表客户端信任所有服务端证书,不代表HTTPS握手逻辑符合站点要求:- 若站点部署在AWS ALB/CloudFront的多域名承载环境下,Vert.x旧版本默认关闭SNI(服务器名称指示),握手时未携带目标域名信息,会被负载均衡转发到默认fallback站点,该站点未配置对应IP白名单,直接返回403
- 传入
https://开头的绝对地址时冗余调用.ssl(true),部分旧版本Vert.x会因为该配置重复触发SSL参数初始化异常,导致握手时域名校验逻辑失效,请求被转发到未配置白名单的节点。
- HTTP协议行为差异触发拦截
Vert.x WebClient默认HTTP行为和JDK原生客户端存在细微差异:比如旧版本默认不会自动携带Connection: keep-alive头、默认重定向跟随策略和JDK不一致(若目标路由存在跳转,Vert.x可能直接返回跳转节点的403响应而非跟随跳转),这类行为差异也可能触发服务端访问控制规则。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

