如何使用Spring Boot 3.1 SSL?


SSL 捆绑包是 Spring Boot 3.1 的一个有用功能。

Spring Boot 3.1引入了SSL包的概念,用于配置和消费定制的SSL信任包,如密钥库、证书和私钥。一旦配置好,就可以使用配置属性或API将捆绑包应用于一个或多个连接。

配置SSL捆绑包
用于配置SSL信任包的属性在application.yaml或application.properties文件中属于spring.ssl.bundle前缀。有两个顶层分组,以反映配置不同类型的信任包所需的独特信息。

  • spring.ssl.bundle.jks可以用来配置使用Java keystore文件的包。
  • spring.sll.bundle.pem可以用来配置使用PEM编码的文本文件的捆绑包。

每种类型都可以配置一个或多个bundle,每个配置的bundle都有一个用户提供的名称。这个名字在用属性应用捆绑包或用API检索捆绑包时被使用。

下面的application.yaml文件示例显示了两个SSL捆绑包的配置。第一个被命名为服务器,定义了一个Java Keystore文件(PKCS #12格式),可用于保护一个嵌入式Web服务器。第二个被命名为客户端,定义了一个带有PEM编码证书文件的信任存储,可用于保护客户端与需要客户端认证的服务器的连接。

spring:
  ssl:
    bundle:
      jks:
        server:
          key:
            alias: "server"
          keystore:
            location: "classpath:server.p12"
            password: "secret"
            type: "PKCS12"
      pem:
        client:
          truststore:
            certificate: "classpath:client.crt"

确保REST客户端的安全
Spring Boot 3.1中启用的SSL功能的一个令人兴奋的新领域是REST客户端的配置。Spring Boot对定制RestTemplate或WebClient的支持现在包括应用SSL捆绑的能力,以确保客户端和REST服务之间的连接。

RestTemplateBuilder有一个新的setSslBundle()方法,接受从自动配置的SslBundles中检索的SSL捆绑,如本例所示:

@Service
public class MyService {

    private final RestTemplate restTemplate;

    public MyService(RestTemplateBuilder restTemplateBuilder, SslBundles sslBundles) {
        this.restTemplate = restTemplateBuilder.setSslBundle(sslBundles.getBundle("mybundle")).build();
    }

}


确保数据库连接的安全性
Spring Boot使配置用于从应用程序连接到数据服务的客户端库变得容易。这些客户端库是使用三个级别的Java安全和SSL API中的任何一个进行配置的API的好例子。

在3.1之前,Spring Boot提供自动配置的许多数据服务都有某种形式的SSL配置。但是,不同服务的支持程度和用于配置的属性并不一致。现在,大多数数据服务的自动配置属性都有类似的ssl结构,为不同服务提供了更高的一致性:

  • Cassandra - spring.cassandra.ssl
  • Couchbase - spring.couchbase.env.ssl
  • Elasticsearch - spring.elasticsearch.restclient.ssl
  • MongoDB - spring.data.mongodb.ssl
  • Redis - spring.data.redis.ssl

大多数服务都有一个*.ssl.enabled属性,它将在客户端库中使用Java运行时cacerts中包含的信任材料启用SSL支持。一个*.ssl.bundle属性适用于一个命名的SSL包,以启用客户端库的SSL支持,并使用来自该包的自定义信任材料。这使得配置更加一致,并允许将相同的信任材料应用于多个连接,减少属性或YAML配置的数量。

为了提供这种水平的一致性,以前的一些与SSL相关的属性已被废弃。更多细节见配置属性的变化日志。

JDBC连接是这个列表中一个明显的遗漏。我们计划在即将发布的Spring Boot中对JDBC连接采用SSL捆绑方式。


保护嵌入式Web服务器的安全
Spring Boot支持的所有嵌入式Web服务器都可以通过使用server.ssl.*属性配置为用SSL保护传入的连接。自Spring Boot诞生以来,就一直支持Java keystore文件,而自2.7以来,就一直支持PEM编码的文件。

server.ssl前缀下的属性数量随着时间的推移而增加,由于缺乏结构,很难分辨哪些属性可以一起使用,哪些是互斥的。以前的server.ssl.*属性继续被支持,但是一个新的server.ssl.bundle属性可以用来将配置好的SSL捆绑应用到嵌入式Web服务器。

下面的两个例子在功能上是一样的:

例子1
server:
  ssl:
    key-alias: “server”
    key-password: “keysecret”
    key-store: "classpath:server.p12"
    key-store-password: "storesecret"
    client-auth: NEED  

例子2
spring:
  ssl:
    bundle:
      jks:
        web-server:
          key:
            alias: "server"
            password: “keysecret”
          keystore:
            location: "classpath:server.p12"
            password: "storesecret"
server:
  ssl:
    bundle: “web-server”
    client-auth: NEED

例子1代表的旧结构更简洁,但例子2新的结构减少了错误配置的机会,并允许在多个连接上使用同一个SSL捆绑包。

management.server.ssl和spring.rsocket.server.ssl属性也做了类似修改。