在Spring Boot中使用自签名证书的HTTPS

2023/05/17

1. 概述

在本教程中,我们将学习如何在Spring Boot中启用HTTPS。为此,我们还将生成一个自签名证书,并配置一个简单的应用程序。

延伸阅读

Spring Boot Security自动配置

Spring Boot默认Spring Security配置的快速实用指南。

阅读更多

Spring Security Java配置简介

Spring Security的Java配置快速实用指南

阅读更多

2. 生成自签名证书

在开始之前,我们将创建一个自签名证书。我们将使用以下任一证书格式:

  • PKCS12:公钥加密标准是一种密码保护的格式,可以包含多个证书和密钥;这是一种行业广泛使用的格式。
  • JKS:Java KeyStore类似于PKCS12;它是一种专有格式,仅限于Java环境。

我们可以使用keytool或OpenSSL工具从命令行生成证书。Keytool随Java运行时环境一起提供,OpenSSL可以从这里下载。

为了简单,我们使用keytool。

2.1 生成密钥库

现在我们将创建一组加密密钥,并将它们存储在密钥库中。

我们可以使用以下命令生成PKCS12密钥库格式:

keytool -genkeypair -alias tuyucheng -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore tuyucheng.p12 -validity 3650

我们可以在同一个密钥库中存储任意数量的密钥对,每个密钥对都由一个唯一的别名标识。

为了以JKS格式生成我们的密钥库,我们可以使用以下命令:

keytool -genkeypair -alias tuyucheng -keyalg RSA -keysize 2048 -keystore tuyucheng.jks -validity 3650

我们建议使用PKCS12格式,这是一种行业标准格式。因此,如果我们已经有了JKS密钥库,我们可以使用以下命令将其转换为PKCS12格式:

keytool -importkeystore -srckeystore tuyucheng.jks -destkeystore tuyucheng.p12 -deststoretype pkcs12

我们必须提供源密钥库密码并设置新的密钥库密码。稍后我们需要用到别名和密钥库密码。

3. 在Spring Boot中启用HTTPS

Spring Boot提供了一组声明式的server.ssl.*属性。我们将在示例应用程序中使用这些属性来配置 HTTPS。

我们从一个带有Spring Security的简单Spring Boot应用程序开始,该应用程序包含一个由“/welcome”端点处理的欢迎页面。

然后我们将上一步生成的名为“tuyucheng.p12”的文件复制到项目的“src/main/resources/keystore”目录中。

3.1 配置SSL属性

现在我们将配置SSL相关属性:

server.ssl.enabled=true
# The format used for the keystore
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:keystore/tuyucheng.p12
# The password used to generate the certificate
server.ssl.key-store-password=password
# The alias mapped to the certificate
server.ssl.key-alias=tuyucheng

由于我们使用的是支持Spring Security的应用程序,因此我们将其配置为仅接受HTTPS请求:

server.ssl.enabled=true

4. 调用HTTPS URL

现在我们已经在应用程序中启用了HTTPS,让我们转到客户端,并探索如何使用自签名证书调用HTTPS端点。

首先,我们需要创建一个信任库。由于我们已经生成了一个PKCS12文件,因此我们可以使用与信任库相同的文件。让我们为信任库详细信息定义新属性:

#trust store location
trust.store=classpath:keystore/tuyucheng.p12
#trust store password
trust.store.password=password

然后我们需要准备一个带有信任库的SSLContext并创建一个自定义的RestTemplate:

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = HttpsEnabledApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ActiveProfiles("ssl")
class HttpsApplicationIntegrationTest {

    private static final String WELCOME_URL = "https://localhost:8443/welcome";

    @Value("${trust.store}")
    private Resource trustStore;

    @Value("${trust.store.password}")
    private String trustStorePassword;

    RestTemplate restTemplate() throws Exception {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build();
        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
        HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(factory);
    }
}

为了演示,让我们确保Spring Security允许任何传入请求:

@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
              .antMatchers("/**")
              .permitAll();
        return http.build();
    }
}

最后,我们可以调用HTTPS端点:

@Test
void whenGETanHTTPSResource_thenCorrectResponse() throws Exception {
    ResponseEntity<String> response = restTemplate().getForEntity(WELCOME_URL, String.class, Collections.emptyMap());
    
    assertEquals("<h1>Welcome to Secured Site</h1>", response.getBody());
    assertEquals(HttpStatus.OK, response.getStatusCode());
}

5. 总结

在本文中,我们首先学习了如何生成自签名证书以在Spring Boot应用程序中启用HTTPS。然后我们讨论了如何调用支持HTTPS的端点。

与往常一样,我们可以在GitHub仓库上找到完整的源代码。

最后,要运行代码示例,我们需要在pom.xml中取消对以下start-class属性的注释:

<start-class>cn.tuyucheng.taketoday.ssl.HttpsEnabledApplication</start-class>

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章