如何在Jetty的InetAccessHandler中使用X-Forwarded-For获取真实客户端IP?
当然可以!Jetty原生就支持处理X-Forwarded-For这类转发头,只需要做两个关键配置,就能让InetAccessHandler用真实客户端IP而非负载均衡器IP来做访问限制。
第一步:配置Jetty信任负载均衡器,启用转发头解析
Jetty的HttpConfiguration内置了转发头处理能力,你需要明确告诉Jetty哪些IP是可信的负载均衡器/反向代理,这样它才会安全地解析X-Forwarded-For头(避免恶意客户端伪造该头绕过限制)。
代码配置方式
HttpConfiguration httpConfig = new HttpConfiguration(); // 初始化转发头处理器,指定可信的负载均衡器IP(单个或IP段都支持) ForwardedRequestCustomizer forwardedCustomizer = new ForwardedRequestCustomizer(); forwardedCustomizer.setTrustedProxies(List.of("192.168.1.100", "10.0.0.0/24")); httpConfig.addCustomizer(forwardedCustomizer);
XML配置文件方式(jetty.xml)
<Configure id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration"> <Call name="addCustomizer"> <Arg> <New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"> <Set name="trustedProxies"> <Array type="java.lang.String"> <Item>192.168.1.100</Item> <Item>10.0.0.0/24</Item> </Array> </Set> </New> </Arg> </Call> </Configure>
重点提醒:trustedProxies必须设置,否则Jetty会直接忽略转发头——这是安全机制,防止外部客户端伪造X-Forwarded-For绕过IP限制。
第二步:确保InetAccessHandler使用解析后的真实IP
当你配置好ForwardedRequestCustomizer后,Jetty会自动把解析出的真实客户端IP存入Request的RemoteAddr属性中,而InetAccessHandler默认就是基于这个属性做IP校验的。所以只要第一步配置正确,InetAccessHandler会自动切换为使用真实客户端IP。
只需保证InetAccessHandler处于Handler链的上游(先执行IP校验)即可,比如代码中:
InetAccessHandler inetAccessHandler = new InetAccessHandler(); // 设置IP访问规则:允许特定IP段,拒绝其他所有 inetAccessHandler.include("192.168.2.0/24"); inetAccessHandler.exclude("0.0.0.0/0"); // 将InetAccessHandler加入Handler链最前端 Server server = new Server(); server.setHandler(inetAccessHandler); // 挂载你的业务Handler到InetAccessHandler之后 inetAccessHandler.setHandler(new YourBusinessRequestHandler());
验证配置有效性
你可以开启Jetty的调试日志,查看org.eclipse.jetty.server.ForwardedRequestCustomizer的日志输出,确认它是否正确解析了X-Forwarded-For头并替换了RemoteAddr。也可以在业务Handler中打印request.getRemoteAddr(),检查输出是否为真实客户端IP。
内容的提问来源于stack exchange,提问作者Nicholas DiPiazza

