【发布时间】:2021-11-22 23:32:57
【问题描述】:
目的:在 Spring Boot Web 应用中获取用户的远程地址(即request.getRemoteAddr())。
简介:
众所周知,getRemoteAddr 方法返回直接调用者的地址,该调用者可能是代理服务器或原始用户和最终目标服务器之间的任何其他服务器(如果有的话)。要找到用户的真实地址,需要查看其他标题(例如X-Forwarded-For)。但是我发现 Tomcat(这是我们的 Web 容器)有一个名为 RemoteIpFilter 的过滤器,它通过复制原始地址来解决这个问题,存储在另一个标题(例如 X-Forwarded-For)中,以便调用 request.getRemoteAddr() 给你原地址。
我在代码中添加了过滤器,一切正常:
@Bean
FilterRegistrationBean<RemoteIpFilter> remoteIpFilter() {
val filter = new FilterRegistrationBean<>(new RemoteIpFilter());
filter.addUrlPatterns("/*");
return filter;
}
但是,有一个问题;当请求是多部分请求时,Spring 会拒绝它:
The request was rejected because the header value "multipart/mixed; boundary="----=_Part_0_blahblah"; charset=utf-8" is not allowed.
我可以看到抛出异常是因为 Spring 的 FilterChainProxy 过滤器将请求包装在 StrictFirewalledRequest 中,这反过来又检查了哪些是允许的,哪些是不允许的(例如,上述内容类型是不允许的)。
除了将RemoteIpFilter 过滤器放在FilterChainProxy 过滤器之前,我找不到上述问题的合适解决方案:
// right before the tracing filter!
filter.setOrder(SleuthWebProperties.TRACING_FILTER_ORDER - 1);
问题
- 使用
RemoteIpFilter是个好主意吗? - 有没有更好的方法来解决上述问题?
-
RemoteIpFilter的最佳订单号是多少?
谢谢。
【问题讨论】:
-
您使用的是什么版本的 Spring Boot?您是否尝试使用
server.forward-headers-strategy=NATIVE(添加了RemoteIpValve)而不是RemoteIpFilter? -
嗯,我不知道。有趣的是,您甚至不需要设置该属性,因为 Spring Boot 会检测环境 (K8S) 并自动激活阀门。我遇到的问题是我的 Nginx 配置替换了 Forwarded-For 标头,而不是附加到它。请您发表您的评论作为答案还是我应该这样做?
-
我无法完全解释
RemoteIpFilter是如何导致multipart/mixed内容被拒绝的,所以最好提供答案。
标签: spring spring-boot tomcat