【问题标题】:Jetty with SSL in Spring Boot 1.2.1Spring Boot 1.2.1 中带有 SSL 的码头
【发布时间】:2015-02-04 11:22:01
【问题描述】:

我应该如何在 Spring Boot 1.2.x 中使用 SSL 连接器配置 Jetty?

以下配置适用于 Spring boot 1.1.6,但在 1.2.1 版本中出现 'SslSocketConnector cannot be resolved to a type' 错误。

@Configuration
@EnableAutoConfiguration
public class OptosoftOAuthSecurityApplication implements
        EmbeddedServletContainerCustomizer {

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

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        if (container instanceof JettyEmbeddedServletContainerFactory) {
            customizeJetty((JettyEmbeddedServletContainerFactory) container);
        }
    }

    public void customizeJetty(
            JettyEmbeddedServletContainerFactory containerFactory) {
        containerFactory.addServerCustomizers(jettyServerCustomizer());
    }

    @Bean
    public JettyServerCustomizer jettyServerCustomizer() {
        return 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);
                }

                // THIS CLASS cannot be resolved !!!!!!  
                SslSocketConnector sslConnector = new SslSocketConnector(
                        sslContextFactory);
                sslConnector.setPort(9443);
                sslConnector.setMaxIdleTime(60000);
                server.addConnector(sslConnector);
            }
        };
    }

    @Bean
    @ConditionalOnMissingBean(RequestContextListener.class)
    public RequestContextListener requestContextListener() {
        return new RequestContextListener();
    }
}

我的 pom.xml(Spring Boot 版本在父 POM 中是 1.2.1):-

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
    </dependencies>

【问题讨论】:

    标签: ssl spring-boot embedded-jetty jetty-9


    【解决方案1】:

    您尝试使用的类特定于 Jetty 8,但 Spring Boot 1.2.x 默认使用 Jetty 9。在 Spring Boot 1.2 中,您现在可以在 application.properties 中以声明方式配置 SSL。这在spring-boot-sample-jetty-ssl 中有说明。

    您可以用application.properties 中声明的以下属性替换您的EmbeddedServletContainerCustomizer 实现:

    server.port = 9443
    server.ssl.key-store = classpath:jetty-ssl.keystore
    server.ssl.key-store-password = jetty6
    

    Spring Boot 仅支持单个连接器的声明式配置。如果您希望服务器可以通过 HTTP 和 HTTPS 访问,那么您必须以编程方式配置其中之一。我建议以编程方式配置 HTTP 连接器,因为涉及的代码更少:

    @Bean
    public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
        return new EmbeddedServletContainerCustomizer() {
    
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                if (container instanceof JettyEmbeddedServletContainerFactory) {
                    configureJetty((JettyEmbeddedServletContainerFactory) container);
                }
            }
    
            private void configureJetty(JettyEmbeddedServletContainerFactory jettyFactory) {
                jettyFactory.addServerCustomizers(new JettyServerCustomizer() {
    
                    @Override
                    public void customize(Server server) {
                        ServerConnector serverConnector = new ServerConnector(server);
                        serverConnector.setPort(8080);
                        server.addConnector(serverConnector);
                    }
                });
            }
        };
    }
    

    【讨论】:

    • 如何指定HTTP端口?
    • 您想同时配置 HTTPS 和 HTTP 访问吗?
    • 您需要以编程方式配置其中之一。我已经更新了我的答案。
    • 日志显示;“已启动 ServerConnector@5032f2b7{SSL-HTTP/1.1}{0.0.0.0:8443} 已启动 ServerConnector@40dcf583{HTTP/1.1}{0.0.0.0:8080} .s.b.c.e.j.JettyEmbeddedServletContainer : Jetty 在端口 8443 (ssl-http/1.1, http/1.1)、8080 (http/1.1) 上启动“但是,我无法使用 https://localhost:8443 访问任何端点。有什么线索会导致这种情况吗?
    • 在不知道错误是什么的情况下很难判断。也许你的证书有问题?查看我之前链接到的示例,看看是否有帮助。您可以将 EmbeddedServletContainerCustomizer bean 添加到其中以获得两个连接器,并查看它是否适用于 HTTP 和 HTTPS。
    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 2015-04-12
    • 2020-12-29
    • 1970-01-01
    • 2018-10-05
    • 2020-09-29
    • 1970-01-01
    • 2014-11-25
    相关资源
    最近更新 更多