You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:30:59