Spring Boot 3.0 应用 HTTP 到 HTTPS 技术改造方案
Spring Boot 3.0 应用 HTTP 到 HTTPS 技术改造方案
概述
本方案详细介绍了将基于 Spring Boot 3.0.0 的 JavaWeb 应用从 HTTP 迁移到 HTTPS 所需的所有步骤,包括证书获取、配置更改、重定向设置和后续维护。
一、证书准备与管理
1.1 证书获取选项
证书类型 | 优点 | 缺点 | 适用场景 |
Let's Encrypt (免费) | 免费,自动化,90天有效期 | 需要定期更新 | 大多数网站,特别是中小型项目 |
商业证书 | 更长有效期,保险保障,浏览器信任度高 | 需要付费 | 企业级应用,电商网站 |
自签名证书 | 免费,立即可用 | 浏览器会显示警告,不适合生产环境 | 开发和测试环境 |
1.2 使用 Let's Encrypt 获取证书(推荐)
# 安装 Certbot
sudo apt update
sudo apt install certbot# 获取证书(使用 standalone 模式)
sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com# 或者使用 webroot 模式(如果Nginx/Apache已在运行)
sudo certbot certonly --webroot -w /path/to/your/webroot -d yourdomain.com -d www.yourdomain.com
证书将存储在 /etc/letsencrypt/live/yourdomain.com/
目录下,包含:
fullchain.pem
:证书链文件privkey.pem
:私钥文件cert.pem
:证书文件chain.pem
:中间证书文件
1.3 证书转换为 Java Keystore 格式
# 将 PEM 文件转换为 PKCS12 格式
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root# 将 PKCS12 转换为 JKS 格式(如果需要)
keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias tomcat
二、Spring Boot 应用配置
2.1 application.properties/yml 配置
# HTTPS 配置
server.port=8443
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=your_password
server.ssl.key-alias=tomcat# HTTP 重定向端口(可选)
server.http.port=8080# 如果需要同时支持 HTTP 和 HTTPS
server.ssl.enabled=true
server.port=443
或者使用 YAML 格式:
server:port: 8443ssl:enabled: truekey-store-type: PKCS12key-store: classpath:keystore.p12key-store-password: your_passwordkey-alias: tomcathttp:port: 8080
2.2 编程方式配置 HTTPS 重定向
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;@Configuration
@EnableWebSecurity
public class HttpsRedirectConfig {// 配置 HTTP 自动重定向到 HTTPS@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.requiresChannel(channel -> channel.anyRequest().requiresSecure()).authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll());return http.build();}// 配置 Tomcat 同时支持 HTTP 和 HTTPS@Beanpublic ServletWebServerFactory servletContainer() {TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();tomcat.addAdditionalTomcatConnectors(createHttpConnector());return tomcat;}private Connector createHttpConnector() {Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");connector.setScheme("http");connector.setPort(8080); // HTTP 端口connector.setSecure(false);connector.setRedirectPort(8443); // 重定向到 HTTPS 端口return connector;}
}
三、Web 服务器配置(如果使用反向代理)
3.1 Nginx 配置示例
server {listen 80;server_name yourdomain.com www.yourdomain.com;# 重定向所有 HTTP 请求到 HTTPSreturn 301 https://$server_name$request_uri;
}server {listen 443 ssl http2;server_name yourdomain.com www.yourdomain.com;# SSL 证书配置ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;# SSL 优化配置ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;ssl_prefer_server_ciphers off;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;# 安全头部add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;add_header X-Frame-Options DENY;add_header X-Content-Type-Options nosniff;add_header X-XSS-Protection "1; mode=block";# 代理到 Spring Boot 应用location / {proxy_pass http://localhost:8080; # Spring Boot 应用的 HTTP 端口proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}# 用于 Certbot 证书续订location ~ /.well-known {allow all;}
}
3.2 Apache 配置示例
<VirtualHost *:80>ServerName yourdomain.comServerAlias www.yourdomain.com# 重定向到 HTTPSRedirect permanent / https://yourdomain.com/
</VirtualHost>
<VirtualHost *:443>ServerName yourdomain.comServerAlias www.yourdomain.com# SSL 配置SSLEngine onSSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pemSSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem# 安全头部Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"Header always set X-Frame-Options DENYHeader always set X-Content-Type-Options nosniff# 代理配置ProxyPreserveHost OnProxyPass / http://localhost:8080/ProxyPassReverse / http://localhost:8080/# 传递协议信息给后端RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
四、应用层调整
4.1 确保应用正确处理 HTTPS
@Configuration
public class WebConfig implements WebMvcConfigurer {// 确保生成的 URL 使用 HTTPS@Beanpublic FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new ForwardedHeaderFilter());registration.addUrlPatterns("/*");return registration;}
}
4.2 更新所有绝对URL引用
检查并更新所有代码中的绝对URL引用,确保它们使用HTTPS:
// 在代码中使用相对路径或配置的基URL
@Value("${app.baseUrl}")
private String baseUrl;public String generateAbsoluteUrl(String path) {return baseUrl + path;
}
五、证书自动续订
5.1 设置 Certbot 自动续订
# 测试续订命令
sudo certbot renew --dry-run# 设置定时任务自动续订
sudo crontab -e
# 添加以下行(每天凌晨2点检查续订)
0 2 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
5.2 证书更新后重新加载配置
创建证书更新后的处理脚本:
#!/bin/bash
# /etc/letsencrypt/renewal-hooks/post/reload-springboot.sh# 将新证书转换为 Java Keystore 格式
openssl pkcs12 -export -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem \-inkey /etc/letsencrypt/live/yourdomain.com/privkey.pem \-out /path/to/keystore.p12 -name tomcat -password pass:your_password# 重新启动或重载 Spring Boot 应用
systemctl restart your-springboot-service
六、测试与验证
6.1 使用 OpenSSL 测试
# 测试 SSL 连接
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com# 检查证书详细信息
openssl x509 -in /path/to/cert.pem -text -noout
6.2 在线 SSL 检查工具
使用以下工具验证配置:
- SSL Labs SSL Test (SSL Server Test (Powered by Qualys SSL Labs))
- Qualys SSL Server Test
- HTTP Security Headers Check
6.3 应用程序健康检查
确保健康检查端点可通过 HTTPS 访问:
@RestController
public class HealthController {@GetMapping("/health")public ResponseEntity<String> health() {return ResponseEntity.ok("Application is healthy over HTTPS!");}
}
七、回滚计划
如果 HTTPS 迁移遇到问题,可按以下步骤回滚:
- 恢复原来的 application.properties 配置
- 如果使用了反向代理,恢复原来的 Nginx/Apache 配置
- 重启应用和 Web 服务器
- 更新 DNS 记录(如果需要)
八、监控与维护
8.1 证书过期监控
设置监控告警,在证书到期前通知:
# 检查证书过期日期
openssl x509 -enddate -noout -in /etc/letsencrypt/live/yourdomain.com/cert.pem# 使用监控工具如 Nagios、Zabbix 或 Prometheus 监控证书有效期
8.2 日志监控
确保监控 SSL/TLS 相关错误日志:
# 在 application.properties 中增加 SSL 相关日志
logging.level.org.apache.tomcat.util.net=INFO
logging.level.org.apache.coyote=INFO
总结
将 Spring Boot 3.0.0 应用从 HTTP 迁移到 HTTPS 需要以下关键步骤:
- 获取和配置 SSL 证书 - 选择适合的证书类型并正确配置
- 更新 Spring Boot 配置 - 配置 SSL 并设置 HTTP 到 HTTPS 的重定向
- Web 服务器配置 - 如果使用反向代理,配置 SSL 终止和重定向
- 应用层调整 - 确保应用正确处理 HTTPS 请求和生成 HTTPS URL
- 自动化证书管理 - 设置证书自动续订流程
- 全面测试 - 验证 HTTPS 功能和安全头设置
- 建立监控 - 监控证书有效期和 SSL/TLS 相关错误
此方案提供了从开始到维护的完整流程,确保迁移过程顺利且可持续维护。