Spring server.forward-headers-strategy NATIVE vs FRAMEWORK

我最近将spring boot从1.x升级到2.y,并面临这个问题,其中heauoas链接是使用方案而不是.httphttps

后来我发现,对于弹簧靴2.2 +,必须使用以下属性

server.forward-headers-strategy=NATIVE

它可以有一个 或 或 。NATIVEFRAMEWORKNONE

NONE属性非常简单,它完全禁用了正向标头的使用。

但是没有关于 vs 的明确文档。我在很多地方都提到在大多数情况下效果最好。但是,当我们使用这些属性时,没有解释幕后究竟发生了什么。NATIVEFRAMEWORKNATIVE

这里的文档没有提供足够的信息让我在原生/框架之间进行选择。它所说的只是谁处理相应值的转发标头。Servlet 容器?还是弹簧框架?但它带回了原点1。我应该让容器来处理它吗?还是框架?我什么时候应该更喜欢一个而不是另一个?

我正在使用REST Web应用程序与外部tomcat并生成链接。Hateoas

我如何决定是使用还是财产?什么时候应该优先于另一个,为什么?NATIVEFRAMEWORK

我的弹簧靴版本:2.4.6

我已经尝试过的参考资料:

编辑:

我尝试了这两种解决方案,并且为我工作,但不是在外部雄猫环境中。我创建了一个新的弹簧引导Web应用程序,其中包含嵌入式tomcat和两者,并且可以工作。frameworknativenativeframework


答案 1

框架

FRAMEWORK使用Spring的支持来处理转发的标头。例如,当 .ForwardedHeaderFilterserver.forward-headers-strategy=framework

@Bean
@ConditionalOnMissingFilterBean(ForwardedHeaderFilter.class)
@ConditionalOnProperty(value = "server.forward-headers-strategy", havingValue = "framework")
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
    ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
    FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter);
    registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
    registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return registration;
}

ForwardedHeaderFilter处理非标准标头 、 、 、 和 。X-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-SslX-Forwarded-Prefix

本地

NATIVE使用基础容器对转发标头的本机支持。底层容器意味着雄猫,码头,网等。例如,由 Spring Boot 自动配置的嵌入式 Tomcat 可处理非标准标头 、 、 、 、 但不能处理 。X-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-SslX-Forwarded-Prefix

X 转发前缀

例如,API 网关在 上运行,API 服务在 上运行。将 API 网关路由转发到 API 服务。包含标头的请求:localhost:8080sga-bookinglocalhost:20000/sga-bookingsga-bookinglocalhost:8080/sga-booking

forwarded = proto=http;host="localhost:8080";for="0:0:0:0:0:0:0:1%0:46706"
x-forwarded-for = 0:0:0:0:0:0:0:1%0
x-forwarded-proto = http
x-forwarded-prefix = /sga-booking
x-forwarded-port = 8080
x-forwarded-host = localhost:8080
host = 192.168.31.200:20000

当处理转发的标头时,包括 ,生成的链接以 开头。如果未处理,则生成的链接以 开头。ForwardedHeaderFilterX-Forwarded-Prefixlocalhost:8080/sga-bookingX-Forwarded-Prefixlocalhost:8080

嵌入式雄猫由Spring Boot自动配置

使用属性 ,方法配置一个具有属性 () 来处理转发的标头。请注意,未处理。server.forward-headers-strategy=nativeorg.springframework.boot.autoconfigure.web.embedded.TomcatWebServerFactoryCustomizer#customizeRemoteIpValveRemoteIpValveserver.tomcat.remoteiporg.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.RemoteipX-Forwarded-Prefix

private void customizeRemoteIpValve(ConfigurableTomcatWebServerFactory factory) {
    Remoteip remoteIpProperties = this.serverProperties.getTomcat().getRemoteip();
    String protocolHeader = remoteIpProperties.getProtocolHeader();
    String remoteIpHeader = remoteIpProperties.getRemoteIpHeader();
    if (StringUtils.hasText(protocolHeader) || StringUtils.hasText(remoteIpHeader)
        || getOrDeduceUseForwardHeaders()) {
        RemoteIpValve valve = new RemoteIpValve();
        valve.setProtocolHeader(StringUtils.hasLength(protocolHeader) ? protocolHeader : "X-Forwarded-Proto");
        if (StringUtils.hasLength(remoteIpHeader)) {
            valve.setRemoteIpHeader(remoteIpHeader);
        }
        valve.setInternalProxies(remoteIpProperties.getInternalProxies());
        try {
            // X-Forwarded-Host by default
            valve.setHostHeader(remoteIpProperties.getHostHeader());
        }
        catch (NoSuchMethodError ex) {
            // Avoid failure with war deployments to Tomcat 8.5 before 8.5.44 and
            // Tomcat 9 before 9.0.23
        }
        // X-Forwarded-Port by default
        valve.setPortHeader(remoteIpProperties.getPortHeader());
        valve.setProtocolHeaderHttpsValue(remoteIpProperties.getProtocolHeaderHttpsValue());
        factory.addEngineValves(valve);
    }
}

外部雄猫

对不起,我从学校毕业后已经很多年没有玩香草雄猫了。下面的Tomcat信息可能是错误的。
要使外部Tomcat句柄转发标头,就像Spring Boot配置的那样,我认为A应该通过添加来配置RemoteIpValve

<Context>
  ...
  <Valve className="org.apache.catalina.valves.RemoteIpValve" 
         hostHeader="X-Forwarded-Host"
         portHeader="X-Forwarded-Port"
       ...
  />
  ...
</Context>

到雄猫?或?在此处查找所有远程 IP 阀属性。请注意,没有与 相关的属性。server.xmlcontext.xmlX-Forwarded-Prefix

Tomcat过滤器RemoteIpFilter可能具有类似的功能。我不知道他们的区别。

参考


答案 2

推荐