在现代web应用开发中,确保数据传输的安全性至关重要。spring boot应用通常使用嵌入式tomcat服务器,而配置ssl/tls是实现https安全通信的关键一步。本教程将详细介绍如何利用godaddy颁发的ssl证书,在spring boot嵌入式tomcat环境中进行配置,从证书的生成、转换到最终的应用集成,提供一套完整的实践指南。
配置HTTPS的第一步是准备好SSL证书文件。GoDaddy通常提供PEM格式的证书。为了在Java环境中使用,我们通常需要将其转换为Java KeyStore (JKS) 或 PKCS12 格式。现代Java版本更推荐使用PKCS12格式。
首先,使用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.csr 文件提交给GoDaddy。GoDaddy验证您的域名所有权后,会颁发SSL证书。您通常会收到一个包含多个文件的压缩包,其中可能包括:
请确保将这些文件下载并解压到您的工作目录。通常,GoDaddy提供的证书是PEM格式。
这是将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
参数说明:
执行此命令时,系统会提示您设置一个导出密码(Export Password)。此密码将用于保护 website_name_here.p12 文件,并在Spring Boot配置中引用。
在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
重要提示:
因此,建议直接在Spring Boot中使用 .p12 文件,避免额外的转换步骤。
在Spring Boot应用中配置SSL,主要是通过自定义 TomcatServletWebServerFactory 来实现。这允许我们配置Tomcat连接器,指向我们准备好的密钥库文件。
创建一个实现 WebServerFactoryCustomizer
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{ 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 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连接器。关键配置项包括:
为了确保所有流量都通过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端口。
通过遵循本教程的步骤,您应该能够在Spring Boot嵌入式Tomcat服务器中成功配置GoDaddy SSL证书,实现安全的HTTPS通信。关键在于正确使用OpenSSL生成和转换证书,并将其整合到Spring Boot的Tomcat配置中。请始终牢记安全最佳实践,以确保您的Web应用在生产环境中安全可靠地运行。