在 Undertow 中启用 HTTPS

Posted

技术标签:

【中文标题】在 Undertow 中启用 HTTPS【英文标题】:Enabling HTTPS in Undertow 【发布时间】:2015-03-10 11:54:46 【问题描述】:

我们有一个有效的 Apache mod_ssl 配置。我想为 Undertow 启用 HTTPS 支持,以便它同时侦听 http 和 https,从而消除对 Apache 的需求。

我查看了 Undertow 的 javadocs。 Undertow.Builder 类有两个带有以下签名的 addHttpsListener 方法:

   public Builder addHttpsListener(int port, String host, 
       KeyManager[] keyManagers, TrustManager[] trustManagers);
   public Builder addHttpsListener(int port, String host,
       SSLContext sslContext) 

看来我可以在使用 Builder API 引导 Undertow 时使用这些,例如

Undertow server = Undertow.builder()
                    .addHttpsListener(8443, "localhost", sslContext)
                    .build();

我不确定如何创建 SSLContext 变量,或者如何配置 KeyManagers 和 TrustManagers。 有了 mod_ssl 正在使用的证书文件,我该如何继续为 Undertow 启用 HTTPS?

更新:

根据 hwellmann 的回答,我重用了 SslContextFactory.createSslContext() 方法。在此之前,我必须将我的公钥/私钥对转换为 PKCS12 格式并将其导入 Java 密钥库。

在下面给出 SSL 转换转换/导入命令(取自 here 和 here),希望这些对任何人都有用:

# Convert to PKCS12    
$ openssl pkcs12 -export -out output_cert.pfx -inkey input_cert.key -in input_cert.crt -certfile intermediate.crt

# Import into Java keystore
$ keytool -v -importkeystore -srckeystore output_cert.pfx -srcstoretype PKCS12 -destkeystore output_store.jks -deststoretype JKS

【问题讨论】:

【参考方案1】:

这并不是真正的 Undertow 特定的,它只是从带有证书的密钥库构建 SSL 上下文的问题。

有关与 Undertow 一起使用的示例,请参阅 SslContextFactory.java

【讨论】:

@siphiuel 您能否在此处发布您的最终配置 .java 文件内容作为答案。【参考方案2】:

在 Undertow 源代码中有一个关于如何创建 SslContext 的示例: https://github.com/undertow-io/undertow/blob/e8473ec35c420b782e072723d1e6338548def842/examples/src/main/java/io/undertow/examples/http2/Http2Server.java#L76

SSLContext sslContext = createSSLContext(loadKeyStore("server.keystore"), loadKeyStore("server.truststore"));

...

private static SSLContext createSSLContext(final KeyStore keyStore, final KeyStore trustStore) throws Exception 
    KeyManager[] keyManagers;
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, password("key"));
    keyManagers = keyManagerFactory.getKeyManagers();

    TrustManager[] trustManagers;
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(trustStore);
    trustManagers = trustManagerFactory.getTrustManagers();

    SSLContext sslContext;
    sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keyManagers, trustManagers, null);

    return sslContext;

...

private static KeyStore loadKeyStore(String storeLoc, String storePw) throws Exception 
    InputStream stream = Files.newInputStream(Paths.get(storeLoc));
    if(stream == null) 
        throw new IllegalArgumentException("Could not load keystore");
    
    try(InputStream is = stream) 
        KeyStore loadedKeystore = KeyStore.getInstance("JKS");
        loadedKeystore.load(is, storePw.toCharArray());
        return loadedKeystore;
    

【讨论】:

以上是关于在 Undertow 中启用 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 中启用 appication.properties 中的 undertow 登录

如何在 Undertow 中启用 Access-Control-Allow-Origin?

在 JBOSS EAP 7.1 中,如何将 EJB 和 undertow 的统计启用设置为 True?

如何在嵌入式 Undertow 服务器上启用目录列表和资源服务?

java9+springboot2+undertow2启用http2及server push

如何将 bean 注入 Undertow 中的 servlet 过滤器?