春季启动自定义Jetty SSLContextFactory

时间:2019-07-26 19:18:58

标签: spring spring-boot jetty

通过阅读spring-boot文档,看来定制Jetty服务器的标准方法是实现一个如下所示的类:

  @Component
  public class JettyServerCustomizer 
      implements WebServerFactoryCustomizer<JettyServletWebServerFactory> {

  @Autowired
  private ServerProperties serverProperties;

  @Override
  public void customize(final JettyServletWebServerFactory factory) {
      factory.addServerCustomizers((server) -> {
          // Customize 
      });
  }

}

我对修改SSLContextFactory特别感兴趣。

在调用定制程序之前,通过spring-boot代码进行跟踪,并配置了ssl:

if (getSsl() != null && getSsl().isEnabled()) {
    customizeSsl(server, address);
}
for (JettyServerCustomizer customizer : getServerCustomizers()) {
    customizer.customize(server);
}

customizeSsl是私有方法,因此不能轻易覆盖:

private void customizeSsl(Server server, InetSocketAddress address) {
    new SslServerCustomizer(address, getSsl(), getSslStoreProvider(), getHttp2()).customize(server);
}

一种选择是在定制程序中创建上下文工厂和连接器,然后覆盖服务器上的连接器。这可能会起作用,但是感觉就像我们正在重新创建一堆代码,而spring-boot已经在做这些代码,只是为了能够调用SSLContextFactory上的方法。

如果我们可以以某种方式提供自己的SslServerCustomizer,那么我们就可以进行所需的自定义配置。

有人知道更好的方法吗?

1 个答案:

答案 0 :(得分:0)

就我而言,它的工作原理如下:

@SpringBootApplication
@ComponentScan(basePackages = { "org.demo.jetty.*" })
public class DemoWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoWebApplication.class, args);
    }

    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
        factory.setContextPath("/demo-app");
        factory.addServerCustomizers(getJettyConnectorCustomizer());
        return factory;
    }

    private JettyServerCustomizer getJettyConnectorCustomizer() {
        return server -> {

            final HttpConfiguration httpConfiguration = new HttpConfiguration();
            httpConfiguration.setSecureScheme("https");
            httpConfiguration.setSecurePort(44333);

            SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
            sslContextFactory.setKeyStoreType("PKCS12");
            sslContextFactory.setKeyStorePath("C:/jetty-demo/demo_cert.p12");
            sslContextFactory.setKeyStorePassword("*****");
            sslContextFactory.setKeyManagerPassword("****");

            final HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
            httpsConfiguration.addCustomizer(new SecureRequestCustomizer());
            ServerConnector httpsConnector = new ServerConnector(server,
                    new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                    new HttpConnectionFactory(httpsConfiguration));
            httpsConnector.setPort(44333);

            server.setConnectors(new Connector[] { httpsConnector });
            server.setStopAtShutdown(true);
            server.setStopTimeout(5_000);
        };
    }
}

您还可以定义一个HTTP连接器并将其添加到自定义部分

...
ServerConnector connector = new ServerConnector(server);
    connector.addConnectionFactory(new HttpConnectionFactory(httpConfiguration));        
    connector.setPort(8081);

server.setConnectors(new Connector[]{connector, httpsConnector});
...