在Spring Boot嵌入式Tomcat中配置GoDaddy SSL证书

在Spring Boot嵌入式Tomcat中配置GoDaddy SSL证书

本教程详细指导如何在spring Boot应用中集成goDaddy ssl证书,实现httpS安全通信。内容涵盖使用OpenSSL生成私钥和CSR、获取GoDaddy证书、将证书转换为PKCS12格式,以及在spring boot嵌入式tomcat中配置SSL连接器和强制https重定向。教程强调了现代Java环境中使用PKCS12格式的优势,并提供了清晰的代码示例和最佳实践建议。

引言

在现代web应用开发中,确保数据传输的安全性至关重要。spring boot应用通常使用嵌入式tomcat服务器,而配置ssl/tls是实现https安全通信的关键一步。本教程将详细介绍如何利用godaddy颁发的ssl证书,在spring boot嵌入式tomcat环境中进行配置,从证书的生成、转换到最终的应用集成,提供一套完整的实践指南。

SSL证书准备:从GoDaddy到PKCS12

配置HTTPS的第一步是准备好SSL证书文件。GoDaddy通常提供PEM格式的证书。为了在Java环境中使用,我们通常需要将其转换为Java KeyStore (JKS) 或 PKCS12 格式。现代Java版本更推荐使用PKCS12格式。

1. 生成私钥和证书签名请求 (CSR)

首先,使用OpenSSL工具生成私钥(.key文件)和证书签名请求(.csr文件)。CSR是向证书颁发机构(CA,如GoDaddy)申请SSL证书的必要文件。

openssl req -new -newkey rsa:2048 -nodes -keyout website_name_here.key -out website_name_here.csr

执行此命令后,系统会提示您输入一系列信息,用于生成CSR。请确保“Common Name (e.g. server FQDN or YOUR name)”字段填写您的域名,例如 website_name_here.co。

生成的文件:

  • website_name_here.key: 您的私钥文件。请务必妥善保管,切勿泄露。
  • website_name_here.csr: 证书签名请求文件。

2. 获取GoDaddy SSL证书

将生成的 website_name_here.csr 文件提交给GoDaddy。GoDaddy验证您的域名所有权后,会颁发SSL证书。您通常会收到一个包含多个文件的压缩包,其中可能包括:

  • 您的服务器证书(例如 your_domain.crt 或 gd_bundle-g2-g1.crt 中的第一个证书)。
  • 中间证书链(例如 gd_bundle-g2-g1.crt)。
  • 根证书(通常包含在中间证书链文件中)。

请确保将这些文件下载并解压到您的工作目录。通常,GoDaddy提供的证书是PEM格式。

3. 关键步骤:转换为PKCS12格式

这是将OpenSSL生成的私钥和GoDaddy颁发的证书合并为Java可识别的密钥库格式的关键一步。PKCS12(.p12)是一种行业标准格式,现代Java版本(Java 8u60及更高版本,以及Java 9+)默认支持并推荐使用。

openssl pkcs12 -export -in your_server_certificate.crt -inkey website_name_here.key -out website_name_here.p12 -name website_name_here.co -CAfile gd_bundle-g2-g1.crt -caname root

参数说明:

  • -in your_server_certificate.crt: 您的服务器证书文件。如果GoDaddy提供的是一个包含服务器证书和中间证书的bundle文件,您可能需要将其拆分或确保此文件包含您的服务器证书。通常GoDaddy会提供一个单独的域名证书文件,以及一个包含中间证书和根证书的bundle文件。
  • -inkey website_name_here.key: 步骤1中生成的私钥文件。
  • -out website_name_here.p12: 将要生成的PKCS12密钥库文件。
  • -name website_name_here.co: 证书的别名(alias),在Spring Boot配置中会用到。这里使用您的域名作为别名。
  • -CAfile gd_bundle-g2-g1.crt: GoDaddy提供的中间证书链文件。这个文件通常包含多个证书,用于构建信任链。
  • -caname root: (可选)为CA证书链指定一个别名。

执行此命令时,系统会提示您设置一个导出密码(Export Password)。此密码将用于保护 website_name_here.p12 文件,并在Spring Boot配置中引用。

4. (可选/不推荐)转换为JKS格式的注意事项

在Java 8u60之前的版本中,JKS(Java KeyStore)是Java的默认密钥库格式。虽然您可以使用 keytool 将PKCS12文件进一步转换为JKS格式,但对于现代Java应用,这通常是不必要的,并且不推荐。

# 仅当您需要JKS格式时才执行此步骤,但强烈建议直接使用PKCS12 keytool -importkeystore -deststorepass pwd_here -destkeystore website_name_here.jks -srckeystore website_name_here.p12 -srcstoretype PKCS12

重要提示:

  • Java 9及更高版本默认创建和使用PKCS12格式的密钥库。
  • Java 8u60及更高版本可以直接读取PKCS12格式的密钥库。
  • JKS格式是oracle的专有格式,而PKCS12是行业标准。使用PKCS12可以提高兼容性和安全性。

因此,建议直接在Spring Boot中使用 .p12 文件,避免额外的转换步骤。

Spring Boot嵌入式Tomcat配置

在Spring Boot应用中配置SSL,主要是通过自定义 TomcatServletWebServerFactory 来实现。这允许我们配置Tomcat连接器,指向我们准备好的密钥库文件。

1. 自定义WebServerFactory

创建一个实现 WebServerFactoryCustomizer<TomcatServletWebServerFactory> 接口的组件,用于自定义Tomcat服务器的配置。

import lombok.SneakyThrows; import org.apache.catalina.connector.Connector; import org.apache.coyote.http11.Http11NioProtocol; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component;  import java.net.InetAddress; import java.util.Optional;  @Component public class TomcatEmbedServerCustomConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {      private static final Logger logger = LoggerFactory.getLogger(TomcatEmbedServerCustomConfiguration.class);      // 假设这些是您的配置存储库,实际项目中应从配置文件或环境变量获取     // IWebApplicationServerSettingsRepository appSettinsRepository;     // ApplicationHttpsSettingsEntityRepository applicationHttpsSettingsEntityRepository;      // public TomcatEmbedServerCustomConfiguration(IWebApplicationServerSettingsRepository appSettinsRepository, ApplicationHttpsSettingsEntityRepository applicationHttpsSettingsEntityRepository) {     //     this.appSettinsRepository = appSettinsRepository;     //     this.applicationHttpsSettingsEntityRepository = applicationHttpsSettingsEntityRepository;     // }      @SneakyThrows     @Override     public void customize(TomcatServletWebServerFactory factory) {         logger.info("Setting the Tomcat specific configurations. started");         try {             // 假设从配置或数据库获取端口和地址             // Optional<WebApplicationServerSettingEntity> serverSettingEntity = appSettinsRepository.findById(1);             // if (serverSettingEntity.isPresent()) {             //     factory.setPort(serverSettingEntity.get().getPort().getPORT());             //     factory.setAddress(InetAddress.getByName(serverSettingEntity.get().getHost()));             // }             // 示例:设置默认HTTP端口和地址             factory.setPort(8080); // 默认HTTP端口             factory.setAddress(InetAddress.getByName("0.0.0.0")); // 默认监听所有接口              factory.setServerHeader("Server header of tomcat");              // HTTPS Settings - Begin             // 假设从配置或数据库获取HTTPS设置             boolean useHttps = true; // 示例:启用HTTPS             String keyStorePath = "file:///c:/trash/website_name_here.p12"; // 指向您的PKCS12文件路径             String keyStorePassword = "pwd_here"; // PKCS12文件的密码             String keyAlias = "website_name_here.co"; // 证书别名,与openssl pkcs12 -name 参数一致             int httpsPort = 8443; // HTTPS端口              if (useHttps) {                 logger.info("Setting HTTPS settings....");                 factory.addAdditionalTomcatConnectors(createSslConnector(keyStorePath, keyStorePassword, keyAlias, httpsPort));                 factory.addContextCustomizers(context -> {                     logger.info("Setting HTTPS settings....setting...");                     SecurityConstraint securityConstraint = new SecurityConstraint();                     securityConstraint.setUserConstraint("CONFIDENTIAL");                     SecurityCollection collection = new SecurityCollection();                     collection.addPattern("/*");                     securityConstraint.addCollection(collection);                     context.addConstraint(securityConstraint);                     logger.info("Setting HTTPS settings....setting...Done");                 });             }             logger.info("Setting HTTPS settings....End");             // HTTPS Settings - end              logger.info("Tomcat Server Configuration Host=[" + factory.getAddress() + "] Port=[" + factory.getPort() + "]");             logger.info("Setting the Tomcat specific configurations. ended");         } catch (Exception e) {             logger.error(e.getMessage());             throw e;         }     }      // HTTPS Settings - Begin     private Connector createSslConnector(String keyStorePath, String keyStorePassword, String keyAlias, int httpsPort) {         logger.info("Creating SSL Connector...");          Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");         Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();          connector.setScheme("https");         connector.setSecure(true);         connector.setPort(httpsPort); // 设置HTTPS端口         protocol.setSSLEnabled(true);          protocol.setKeystoreFile(keyStorePath); // 指定PKCS12文件路径         protocol.setKeystorePass(keyStorePassword); // PKCS12文件密码         protocol.setKeyAlias(keyAlias); // 证书别名          logger.info("Creating SSL Connector...Done");         return connector;     }     // HTTPS Settings - End }

在上述代码中,createSslConnector 方法负责创建并配置一个SSL连接器。关键配置项包括:

  • protocol.setKeystoreFile(): 指定PKCS12密钥库文件的路径。请确保路径正确,可以是绝对路径或类路径下的相对路径。
  • protocol.setKeystorePass(): 指定PKCS12文件的密码,即您在 openssl pkcs12 -export 命令中设置的导出密码。
  • protocol.setKeyAlias(): 指定证书的别名,与您在 openssl pkcs12 -export 命令中 -name 参数设置的值一致。

2. HTTP到HTTPS重定向 (可选)

为了确保所有流量都通过HTTPS进行,您可以配置Tomcat将所有HTTP请求重定向到HTTPS。这可以通过添加一个 SecurityConstraint 来实现。

import org.apache.catalina.Context; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;  @Configuration public class SecurityConfig {     @Bean     public TomcatServletWebServerFactory httpsredirectConfig() {         return new TomcatServletWebServerFactory() {             @Override             protected void postProcessContext(Context context) {                 SecurityConstraint securityConstraint = new SecurityConstraint();                 securityConstraint.setUserConstraint("CONFIDENTIAL"); // 要求使用保密传输(即HTTPS)                 SecurityCollection collection = new SecurityCollection();                 collection.addPattern("/*"); // 匹配所有URL                 securityConstraint.addCollection(collection);                 context.addConstraint(securityConstraint);             }         };     } }

这个配置会在Tomcat启动时,为所有请求添加一个安全约束,强制使用HTTPS。当HTTP请求到达时,Tomcat会自动将其重定向到相应的HTTPS端口。

注意事项与最佳实践

  • 密钥库安全:私钥文件(.key)和PKCS12密钥库文件(.p12)包含敏感信息,必须严格保护。不要将其提交到版本控制系统,或以不安全的方式存储。在生产环境中,应使用环境变量、Vault等安全机制来管理密钥库密码。
  • 证书链完整性:确保您的PKCS12文件包含了完整的证书链(服务器证书、中间证书、根证书)。如果缺少中间证书,客户端可能会报告证书不信任的错误。openssl pkcs12 -export 命令的 -CAfile 参数就是用于包含中间证书链的。
  • 别名一致性:在 openssl pkcs12 -export 中使用的 -name 参数(证书别名)必须与Spring Boot配置中 protocol.setKeyAlias() 的值完全一致。
  • 路径正确性:protocol.setKeystoreFile() 中指定的路径必须是Tomcat进程可以访问到的有效路径。
  • 自动续期:SSL证书通常有有效期,需要定期续期。考虑使用自动化工具或流程来管理证书的续期和部署,以避免因证书过期导致的服务中断。
  • 生产环境配置:在生产环境中,通常会将密钥库文件放置在应用外部的安全位置,并通过配置属性(如 application.properties 或 application.yml)或环境变量来引用其路径和密码,而不是硬编码在代码中。

总结

通过遵循本教程的步骤,您应该能够在Spring Boot嵌入式Tomcat服务器中成功配置GoDaddy SSL证书,实现安全的HTTPS通信。关键在于正确使用OpenSSL生成和转换证书,并将其整合到Spring Boot的Tomcat配置中。请始终牢记安全最佳实践,以确保您的Web应用在生产环境中安全可靠地运行。

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享