使用Spring Boot为X-FORWARDED-PROTO配置嵌入式Jetty 9

问题描述 投票:3回答:5

我正在AWS中运行Spring Boot应用程序。应用程序在Elastic Load Balancer(ELB)后面运行。 ELB配置为使用https(端口443)到外部世界,但通过http(端口8080)到应用程序。 ELB配置为通过x-forwarded-proto标头。我正在使用Jetty 9.0.0.M0,Spring Boot 1.1.5 RELEASE

我似乎收到了通过ELB从应用程序发回的不正确的重定向,其中重定向响应以http而不是https的形式返回。现在,我读了here,我应该使用以下方法将“转发”标题设置为true

<Set name="forwarded">true</Set>

我无法看到如何使用Spring Boot中的嵌入式Jetty版本来执行此操作,因为我的源代码中没有XML配置文件。

我看过EmbeddedServletContainerCustomizer基础设施,但我仍然无法得到正确的咒语来让这个设置工作。

该应用程序是在AWS https环境之外构建和测试的,因此应用程序也需要透明地与http一起使用。直接命中应用程序端点而无需通过ELB工作。只是ELB到申请路线不起作用。

有任何想法吗?

spring amazon-web-services https jetty
5个回答
6
投票

我自己有一个类似的问题,而研究时遇到了你的问题。我发现这很容易以编程方式进行,但是在Jetty文档中并没有真正解释过。

Jetty xml配置文件的结构与java API的结构相匹配,因此您可以在代码中复制它。

所以遵循Jetty指南,了解如何使用XML配置文件here进行配置

我能够以编程方式配置嵌入式服务器,如下所示:

    Server server = new Server( port );

    // Create HTTP Config
    HttpConfiguration httpConfig = new HttpConfiguration();

    // Add support for X-Forwarded headers
    httpConfig.addCustomizer( new org.eclipse.jetty.server.ForwardedRequestCustomizer() );

    // Create the http connector
    HttpConnectionFactory connectionFactory = new HttpConnectionFactory( httpConfig );
    ServerConnector connector = new ServerConnector(server, connectionFactory);

    // Make sure you set the port on the connector, the port in the Server constructor is overridden by the new connector
    connector.setPort( port );

    // Add the connector to the server
    server.setConnectors( new ServerConnector[] { connector } );

0
投票

我发现默认的Spring Boot Jetty配置存在一些问题,其中最重要的是启用了SSLLabs Check不喜欢的SSL算法。

无论如何:我找到的解决方案是这样的:

   @Bean
   public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() 
   {
      // Deploy the nuclear option, kill the default Spring Boot factory
      // and replace with mine that disables extra crud.
      JettyEmbeddedServletContainerFactory fac = new JettyEmbeddedServletContainerFactory();
      // This allows ELB to work.
      fac.setUseForwardHeaders( true );
      return fac;
   }

如果您希望SSL端到端,还需要设置许多其他ELB选项。我不得不使用命令行客户端进行一些调整并将运行状况检查更改为TCP:8443 b / c EC2实例证书对负载均衡器看起来无效。


0
投票

以下是Jetty-runner-9.3.6.jar背后的Spring应用程序。在我们的例子中,我们的jetty.xml已经没有任何addConnector,并且尝试仅添加addConnector会出错。

在这里找到它 - https://github.com/george-hawkins/authsite/blob/2c5d61b984a328ef878216a3acfd0ad2593f81b1/src/main/config/etc/jetty.xml

  <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
    <Call name="addCustomizer">
      <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
    </Call>
  </New>

  <Call name="addConnector">
    <Arg>
      <New class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
            <Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config"><Ref refid="httpConfig" /></Arg>
              </New>
            </Item>
          </Array>
        </Arg>
        <Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
      </New>
    </Arg>
  </Call>

这样做是为了修改传递的Request对象,使其看起来像是没有来自代理(用可用和支持的任何X-Forwarded标头替换细节)。

http://archive.eclipse.org/jetty/9.0.0.M4/apidocs/index.html?org/eclipse/jetty/server/ForwardedRequestCustomizer.html

此定制程序查看标头的HTTP请求,指示它已由一个或多个代理转发。具体处理是:

  • X - 转发,主机
  • X - 转发服务器
  • X - 转发,对于
  • X - 转发,原

如果存在这些标头,则更新Request对象,以便不将代理视为请求所在的连接的另一端点


0
投票

尝试在spring启动应用程序中设置以下属性:

server.use-forward-headers=true

这将确保从标题中读取正确的协议。请参阅此处的文档:

https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/html/howto-embedded-servlet-containers.html


-2
投票

我一直无法找到这个问题的简单Jetty 9解决方案。除了建议我升级到Jetty的更高版本(这是一个好建议),我没有收到任何其他建议(此时,你可以看到)

为方便起见,我的解决方案是放弃Jetty,而是使用嵌入式tomcat,其中这个功能在application.properties文件中是一个简单的配置问题。只需将以下行添加到application.properties

server.tomcat.remote_ip_header=x-forwarded-for

这似乎是使用作为Spring Boot的一部分的默认嵌入式tomcat的技巧。

© www.soinside.com 2019 - 2024. All rights reserved.