【问题标题】:Spring Boot + Jetty + SSL PortSpring Boot + Jetty + SSL 端口
【发布时间】:2014-06-09 14:12:06
【问题描述】:

如何配置 Spring Boot 以在 443 处使用 HTTPS 端口运行 Jetty。配置还应注意生成密钥。

简而言之,以下maven插件的等效配置:-

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>keytool-maven-plugin</artifactId>
  <version>1.3</version>
  <executions>
    <execution>
      <phase>generate-resources</phase>
      <id>clean</id>
      <goals>
        <goal>clean</goal>
      </goals>
    </execution>
    <execution>
      <phase>generate-resources</phase>
      <id>genkey</id>
      <goals>
        <goal>generateKeyPair</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <keystore>${project.build.directory}/jetty-ssl.keystore</keystore>
    <dname>cn=my.hostname.tld</dname>
    <!-- put your CN here -->
    <keypass>jetty6</keypass>
    <storepass>jetty6</storepass>
    <alias>jetty6</alias>
    <keyalg>RSA</keyalg>
  </configuration>
</plugin>

和:-

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>maven-jetty-plugin</artifactId>
  <version>6.1.26</version>
  <configuration>
    <jvmArgs>-Xmx2048m -Xms1536m -XX:PermSize=128m -XX:MaxPermSize=256m</jvmArgs>
    <!-- http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin -->
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <connectors>
      <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
        <port>9999</port>
        <maxIdleTime>60000</maxIdleTime>
      </connector>
      <connector implementation="org.mortbay.jetty.security.SslSocketConnector">
        <port>9993</port>
        <maxIdleTime>60000</maxIdleTime>
        <keystore>${project.build.directory}/jetty-ssl.keystore</keystore>
        <password>jetty6</password>
        <keyPassword>jetty6</keyPassword>
      </connector>
    </connectors>
    <contextPath>/</contextPath>
  </configuration>
</plugin>

【问题讨论】:

    标签: embedded-jetty spring-boot


    【解决方案1】:

    从 Spring Boot 1.1.7 开始,您可以通过属性文件中的三个属性将 Jetty 和 Tomcat 配置为使用 SSL,如 Spring Boot documentation 所示

    通过这些属性配置 SSL 将启用 HTTPS 并禁用 HTTP,因为仅使用属性文件不允许同时使用两者。如果您想同时为两者提供服务Spring recommends,您可以通过属性配置 HTTPS (SSL) 并以编程方式配置 HTTP。

    【讨论】:

      【解决方案2】:

      我找到了这个解决方案。这对我来说可以。 此方法可以同时支持 HTTP 和 HTTPS。

      @Component
      public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
          return new EmbeddedServletContainerCustomizer() {
      
              @Override
              public void customize(ConfigurableEmbeddedServletContainer container) {
                  if (container instanceof JettyEmbeddedServletContainerFactory) {
                      customizeJetty((JettyEmbeddedServletContainerFactory) container);
                  }
              }
      
              private void customizeJetty(JettyEmbeddedServletContainerFactory container) {
      
          container.addServerCustomizers(new JettyServerCustomizer() {
      
              @Override
              public void customize(Server server) {
      
                  // HTTP
                  ServerConnector connector = new ServerConnector(server);
                  connector.setPort(requestHttpPort());
      
                  // HTTPS
                  SslContextFactory sslContextFactory = new SslContextFactory();
                  sslContextFactory.setKeyStorePath("mykeystore.jks");
                  sslContextFactory.setKeyStorePassword("1234");
      
                  HttpConfiguration https = new HttpConfiguration();
                  https.addCustomizer(new SecureRequestCustomizer());
      
                  ServerConnector sslConnector = new ServerConnector(
                          server,
                          new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                          new HttpConnectionFactory(https));
                  sslConnector.setPort(requestHttpsPort());
      
                  server.setConnectors(new Connector[] { connector, sslConnector });
      
              }
          });
      }
      

      【讨论】:

        【解决方案3】:

        要将 SSL 连接器添加到 Jetty,您需要在应用程序的配置中声明一个 EmbeddedServletContainerCustomizer bean。这最终将使您能够访问 Jetty Server 实例,您可以在其中使用 Jetty 的 API 进行所需的配置更改。类似的东西:

        @Bean
        public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
            return new EmbeddedServletContainerCustomizer() {
        
                @Override
                public void customize(ConfigurableEmbeddedServletContainer container) {
                    if (container instanceof JettyEmbeddedServletContainerFactory) {
                        customizeJetty((JettyEmbeddedServletContainerFactory) container);
                    }
                }
        
                private void customizeJetty(JettyEmbeddedServletContainerFactory factory) {
                    factory.addServerCustomizers(new JettyServerCustomizer() {
        
                        @Override
                        public void customize(Server server) {
                            SslContextFactory sslContextFactory = new SslContextFactory();
                            sslContextFactory.setKeyStorePassword("jetty6");
                            try {
                                sslContextFactory.setKeyStorePath(ResourceUtils.getFile(
                                        "classpath:jetty-ssl.keystore").getAbsolutePath());
                            }
                            catch (FileNotFoundException ex) {
                                throw new IllegalStateException("Could not load keystore", ex);
                            }
                            SslSocketConnector sslConnector = new SslSocketConnector(
                                    sslContextFactory);
                            sslConnector.setPort(9993);
                            sslConnector.setMaxIdleTime(60000);
                            server.addConnector(sslConnector);
                        }
                    });
                }
            };
        }
        

        Spring Boot 不支持自动生成密钥库。我会继续为此使用 keytool Maven 插件。

        【讨论】:

        • “SslSocketConnector 无法解析为类型”。我在哪里可以找到这门课?
        • 你使用的是什么版本的 Jetty?
        • 那是 8.1.14,如果你使用它的依赖管理,这是 Boot 1.0.2 默认提供的版本。
        • 它对我不起作用。日志显示端口上的 Jetty starterd:9993(没有@0.0.0.0),我无法在浏览器中访问主页127.0.0.1:9993
        【解决方案4】:

        适用于 Spring Boot 较新版本 (2.1.x)。试试下面的代码,基本上 EmbeddedServletContainerCustomizer 和 ConfigurableEmbeddedServletContainer 已经被替换如下:

        import org.eclipse.jetty.http.HttpVersion;
        import org.eclipse.jetty.server.Connector;
        import org.eclipse.jetty.server.HttpConfiguration;
        import org.eclipse.jetty.server.HttpConnectionFactory;
        import org.eclipse.jetty.server.SecureRequestCustomizer;
        import org.eclipse.jetty.server.Server;
        import org.eclipse.jetty.server.ServerConnector;
        import org.eclipse.jetty.server.SslConnectionFactory;
        import org.eclipse.jetty.util.ssl.SslContextFactory;
        import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
        import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
        import org.springframework.boot.web.server.WebServerFactoryCustomizer;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.util.ResourceUtils;
        
        @Configuration
        public class BeanConfiguration {
        
            @Bean
            public WebServerFactoryCustomizer<JettyServletWebServerFactory> webServerFactoryCustomizer() {
        
                return new WebServerFactoryCustomizer<JettyServletWebServerFactory>() {
        
                    @Override
                    public void customize(JettyServletWebServerFactory factory) {
        
                        factory.addServerCustomizers(new JettyServerCustomizer() {
        
                            @Override
                            public void customize(Server server) {
        
                                ServerConnector httpConnector = new ServerConnector(server);
                                httpConnector.setPort(8080);
        
                                SslContextFactory sslContextFactory = new SslContextFactory();
                                try {
                                    sslContextFactory
                                            .setKeyStorePath(ResourceUtils.getFile("classpath:keystore.jks").getAbsolutePath());
                                } catch (Exception e) {
                                }
        
                                sslContextFactory.setKeyStorePassword("password");
        
                                HttpConfiguration httpsConfiguration = new HttpConfiguration();
                                httpsConfiguration.addCustomizer(new SecureRequestCustomizer());
        
                                ServerConnector httpsConnector = new ServerConnector(server,
                                        new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                                        new HttpConnectionFactory(httpsConfiguration));
                                httpsConnector.setPort(8090);
        
                                server.setConnectors(new Connector[] {httpConnector, httpsConnector});
                            }
                        });
        
                    }
                };
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-07-05
          • 2015-08-26
          • 2018-08-23
          • 1970-01-01
          • 2016-12-23
          • 2018-03-18
          • 2019-01-23
          • 1970-01-01
          相关资源
          最近更新 更多