Spring Boot 如何配置 SSL 让内嵌服务器通过 HTTPS 提供服务【免费下载链接】spring-bootSpring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot如果你的 Spring Boot 应用内嵌了 Web 服务器servlet 栈的spring-boot-starter-web默认包含 Tomcatreactive 栈的spring-boot-starter-webflux默认包含 Reactor Netty希望直接通过 HTTPS 对外提供服务Spring Boot 支持用server.ssl.*配置属性声明式地开启 SSL无需自己写连接器代码。适用前提你手上已有证书材料——Java KeyStore 文件JKS 或 PKCS12 格式或 PEM 编码的证书与私钥文件。下面按“KeyStore → PEM → SSL bundle”给出三条配置路径并说明端口限制、双端口并存、SNI、HTTP/2 和证书热加载等边界。用 Java KeyStore 配置 SSL主路径在application.properties或application.yaml中设置server.ssl.*系列属性。文档给出的 KeyStore 配置示例如下server: port: 8443 ssl: key-store: classpath:keystore.jks key-store-password: secret key-password: another-secret其中key-store指向 KeyStore 文件位置key-store-password是 KeyStore 的口令key-password是其中私钥条目的口令。支持的全部属性见org.springframework.boot.web.server.Ssl的 javadoc。配置生效后有一个必须了解的边界应用不再支持 8080 端口的纯 HTTP 连接器。Spring Boot 不支持通过application.properties同时配置 HTTP 和 HTTPS 两个连接器如果你需要两者并存必须用编程方式配置其中一个详见后文“同时保留 HTTP 端口”一节。用 PEM 编码的证书文件配置如果你有 PEM 编码的证书与私钥文件可以直接用以下属性替代 KeyStoreserver: port: 8443 ssl: certificate: classpath:my-cert.crt certificate-private-key: classpath:my-cert.key trust-certificate: classpath:ca-cert.crt私钥文件的格式有要求应尽可能使用 PKCS#8 格式其 PEM 头部是-----BEGIN PRIVATE KEY-----或-----BEGIN ENCRYPTED PRIVATE KEY-----。如果你的文件是其他格式例如 PKCS#1 的-----BEGIN RSA PRIVATE KEY-----或 SEC 1 的-----BEGIN EC PRIVATE KEY-----文档给出用 OpenSSL 转换的命令openssl pkcs8 -topk8 -nocrypt -in input file -out output file命令中的input file与output file需替换为你实际的输入/输出文件路径。用 SSL Bundle 集中管理信任材料除了直接写在server.ssl下Spring Boot 还允许把信任材料定义成具名的SSL bundlespring.ssl.bundle.*再让 Web 服务器按名字引用。JDK KeyStore 类的 bundle 示例spring: ssl: bundle: jks: mybundle: key: alias: application keystore: location: classpath:application.p12 password: secret type: PKCS12PEM 类的 bundle 示例spring: ssl: bundle: pem: mybundle: keystore: certificate: classpath:application.crt private-key: classpath:application.keybundle 定义好后让内嵌 Web 服务器引用它只需一行server: port: 8443 ssl: bundle: example使用 bundle 时注意文档明确给出的限制server.ssl.bundle不能与server.ssl下单独的 Java KeyStore 或 PEM 属性key-store、certificate等组合使用。使用 bundle 时server.ssl.ciphers、server.ssl.enabled-protocols、server.ssl.protocol会被忽略应改用spring.ssl.bundle.type.name.options定义这些选项。另外文档提示可以用 Base64 编码的内容直接替代文件位置属性值以base64:开头即可。完整的 bundle 属性集见org.springframework.boot.autoconfigure.ssl.JksSslBundleProperties与org.springframework.boot.autoconfigure.ssl.PemSslBundleProperties。证书文件更新时热加载 bundle如果信任材料放在外部文件中、且会由外部工具更新可以开启 bundle 的自动重载。文档说明当前支持重载的消费组件是Tomcat Web 服务器、Netty Web 服务器、LDAP 客户端。启用方式spring: ssl: bundle: pem: mybundle: reload-on-update: true keystore: certificate: file:/some/directory/application.crt private-key: file:/some/directory/application.key开启后 Spring Boot 会用文件监视器跟踪证书文件文件变化即重载 bundle例如 Tomcat 会轮换 SSL 连接器中的证书。文件监视器的静默期确认不再变化前的等待时间可用spring.ssl.bundle.watch.file.quiet-period属性配置。一个典型的生产场景证书由 Lets Encrypt 签发、Certbot 续期Spring Boot 本身不申请或续期 Lets Encrypt 证书。文档给出的配置示例spring: ssl: bundle: pem: webserver: reload-on-update: true keystore: certificate: file:/etc/letsencrypt/live/example.com/fullchain.pem private-key: file:/etc/letsencrypt/live/example.com/privkey.pem server: ssl: bundle: webserver/etc/letsencrypt/live下的文件通常是指向/etc/letsencrypt/archive的符号链接文件监视器会跟随符号链接因此目标文件更新时同样能触发重载。兼容的消费组件Tomcat、Netty可以使用更新后的证书而无需重启应用。同时保留 HTTP 端口时如何配置如前所述application.properties只能配置一个连接器HTTPS 配置生效后 8080 上的纯 HTTP 就不可用了。文档的建议是用application.properties配置 HTTPS相对容易HTTP 连接器用编程方式添加。以默认 Tomcat 为例通过WebServerFactoryCustomizer给TomcatServletWebServerFactory追加一个 HTTP Connector仓库中的示例代码MyTomcatConfiguration.javaConfiguration(proxyBeanMethods false) public class MyTomcatConfiguration { Bean public WebServerFactoryCustomizerTomcatServletWebServerFactory connectorCustomizer() { return (tomcat) - tomcat.addAdditionalConnectors(createConnector()); } private Connector createConnector() { Connector connector new Connector(org.apache.coyote.http11.Http11NioProtocol); connector.setPort(8081); return connector; } }代码中的import略完整文件见上述链接。Jetty 场景则是在ConfigurableJettyWebServerFactory上添加JettyServerCustomizer来注册额外的Connector实例。可选扩展SNI 与 HTTP/2多域名 SNI。Tomcat 和 Netty 可以为不同主机名指定各自的信任材料以支持 Server Name IndicationJetty 不支持这种 SNI 配置。前提是先定义好多个 bundle例如web、web-alt1、web-alt2然后server: port: 8443 ssl: bundle: web server-name-bundles: - server-name: alt1.example.com bundle: web-alt1 - server-name: alt2.example.com bundle: web-alt2server.ssl.bundle指定的 bundle 用于默认主机和不支持 SNI 的客户端配置了任何server.ssl.server-name-bundles时这个默认 bundle 必须存在。启用 HTTP/2。用server.http2.enabled属性开启。h2HTTP/2 over TLS与h2cHTTP/2 over TCP都受支持但使用h2时必须同时启用 SSL未启用 SSL 时会使用h2c——例如应用在做了 TLS 终结的代理后面时就有用。如何确认 HTTPS 端口已在监听文档说明内嵌服务器实际监听的端口可以从两个途径获取一是启动日志输出二是更可靠的方式——注册一个ApplicationListenerWebServerInitializedEvent类型的Bean在事件发布时从WebServerInitializedEvent中取出WebServer实例并读取端口事件在容器初始化完成后发布能保证端口值可用。拿到端口后用浏览器或curl按https://host:8443访问你的接口能完成 TLS 握手并返回应用响应即说明配置生效。限制小结server.ssl与server.ssl.bundle两套配置不能混用用 bundle 时ciphers/enabled-protocols/protocol被忽略需写到spring.ssl.bundle.type.name.options。属性方式无法同时挂 HTTP HTTPS 两个连接器必须编程方式补一个。SNI 的server-name-bundles仅适用于 Tomcat 和 NettyJetty 不支持。bundle 热加载仅对 Tomcat、Netty Web 服务器和 LDAP 客户端生效。更多细节可参考仓库中的原始文档内嵌服务器 how-to 与 SSL 参考文档bundle 文件监视静默期的默认值10 秒可在 SslProperties.java 中核对。【免费下载链接】spring-bootSpring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考