如何配置Spring Boot(Jetty):启用SSL并保留非安全健康检查端点
答案:当然可以!
完全可以配置基于Jetty的Spring Boot应用实现这个需求——让负载均衡器通过非HTTPS端点做健康检查,同时强制所有其他请求走HTTPS。下面是具体的实现步骤,一步步来:
1. 配置专属的非SSL连接器用于健康检查
当你设置server.ssl.enabled=true时,Spring Boot会让所有默认的Jetty连接器强制使用HTTPS。所以我们需要手动添加一个只处理健康检查的HTTP连接器,指定单独的端口(比如8081)。
代码实现(自定义Jetty连接器)
创建一个JettyServerCustomizer Bean来添加非SSL连接器:
@Bean public JettyServerCustomizer jettyHealthCheckConnectorCustomizer() { return server -> { // 新建一个非SSL的ServerConnector,专门用于健康检查 ServerConnector httpHealthConnector = new ServerConnector(server); httpHealthConnector.setPort(8081); // 自定义健康检查端口 server.addConnector(httpHealthConnector); }; }
主应用的SSL配置(application.properties)
保持主端口的HTTPS强制配置:
# 主应用HTTPS端口 server.port=8443 server.ssl.enabled=true # SSL证书相关配置 server.ssl.key-store=classpath:your-keystore.jks server.ssl.key-store-password=your-keystore-password server.ssl.key-alias=your-cert-alias
2. 限制非SSL端口仅允许健康检查请求
为了安全,不能让这个非SSL端口接受除健康检查外的任何请求。我们可以用Spring Security来做拦截控制:
Spring Security配置示例
@Configuration @EnableWebSecurity public class AppSecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 允许所有请求访问健康检查端点(仅限非SSL端口) .authorizeHttpRequests(auth -> auth .requestMatchers("/actuator/health").permitAll() // 拒绝非SSL端口上的所有其他请求 .requestMatchers(request -> request.getServerPort() == 8081).denyAll() // 其他所有请求需要认证+HTTPS .anyRequest().authenticated() ) // 强制非健康检查的请求必须使用HTTPS .requiresChannel(channel -> channel .requestMatchers(request -> request.getServerPort() != 8081).requiresSecure() ); return http.build(); } }
别忘了确保Actuator的健康端点暴露出来:
management.endpoints.web.exposure.include=health management.endpoint.health.show-details=always # 可选,根据需求调整
3. 确保HTTPS请求的主机名与证书匹配
当客户端(包括负载均衡器)通过HTTPS访问应用时,请求的主机名必须和SSL证书中的**CN(通用名称)或SAN(主题备用名称)**一致。
- 如果是Kubernetes环境,建议使用通配符证书(比如
*.your-namespace.svc.cluster.local),或者用Cert-Manager自动生成包含Pod/Service主机名的证书。 - 如果是其他负载均衡场景,确保证书里包含负载均衡器用来访问节点的所有主机名(优先用域名,尽量避免直接用IP)。
4. 负载均衡器/容器管理器的配合配置
以Kubernetes为例,你需要在Deployment和Service中配置端口映射,让健康检查流量走非SSL端口:
Deployment端口配置
apiVersion: apps/v1 kind: Deployment metadata: name: your-app-deployment spec: replicas: 3 selector: matchLabels: app: your-app template: metadata: labels: app: your-app spec: containers: - name: your-app-container image: your-app-image:latest ports: - name: https containerPort: 8443 # 主HTTPS端口 - name: health-check containerPort: 8081 # 健康检查用的HTTP端口 livenessProbe: httpGet: path: /actuator/health port: health-check # 指向健康检查端口 initialDelaySeconds: 10 periodSeconds: 5 readinessProbe: httpGet: path: /actuator/health port: health-check initialDelaySeconds: 5 periodSeconds: 3
Service配置
apiVersion: v1 kind: Service metadata: name: your-app-service spec: selector: app: your-app ports: - name: https port: 443 targetPort: https # 转发用户流量到HTTPS端口 - name: health-check port: 8081 targetPort: health-check # 暴露健康检查端口给K8s或外部负载均衡器
这样配置完成后,负载均衡器/K8s可以通过http://<node-ip>:8081/actuator/health做健康检查,而所有用户请求都会被强制走HTTPS,同时HTTPS请求的主机名也会和证书匹配,完全满足你的需求。
内容的提问来源于stack exchange,提问作者toddcscar
相关产品推荐
相关产品推荐

