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

如何在Reactor Netty/Spring WebFlux中获取服务端SSL证书?

在Reactor Netty及Spring WebFlux中获取服务器证书的方案

一、Reactor Netty原生实现

Reactor Netty完全可以实现客户端读取服务器证书,核心是通过自定义SslContext配置,结合SslHandler的握手回调提取证书链:

  1. 构建自定义SslContext,为SslHandler添加握手完成后的监听器
  2. 配置Reactor Netty的HttpClient绑定该SslContext,发起请求触发握手

示例代码:

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import reactor.netty.http.client.HttpClient;
import java.security.cert.Certificate;
import javax.net.ssl.SSLSession;

public class ReactorNettyCertReader {

    public void fetchServerCert(String url) throws Exception {
        // 构建客户端SslContext
        SslContext sslContext = SslContextBuilder.forClient().build();

        HttpClient client = HttpClient.create()
                .secure(sslSpec -> sslSpec.sslContext(sslContext)
                        .handlerConfigurator(sslHandler -> {
                            // 监听握手完成事件,提取证书
                            sslHandler.handshakeFuture().addListener(future -> {
                                if (future.isSuccess()) {
                                    SSLSession sslSession = sslHandler.engine().getSession();
                                    try {
                                        Certificate[] certificates = sslSession.getPeerCertificates();
                                        for (Certificate cert : certificates) {
                                            System.out.println("证书信息:" + cert);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            });
                        }));

        // 发起请求触发握手(实际业务中建议用subscribe替代block)
        client.get()
                .uri(url)
                .response()
                .block();
    }
}

二、Spring WebFlux/WebClient方案

如果使用Spring WebFlux,可以通过自定义ClientHttpConnector配置Reactor Netty客户端,将证书获取逻辑集成到WebClient中:

示例代码:

import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import reactor.netty.http.client.HttpClient;
import java.security.cert.Certificate;
import javax.net.ssl.SSLSession;

@Configuration
public class WebClientCertConfig {

    public WebClient webClientWithCertReader() throws Exception {
        SslContext sslContext = SslContextBuilder.forClient().build();

        HttpClient httpClient = HttpClient.create()
                .secure(sslSpec -> sslSpec.sslContext(sslContext)
                        .handlerConfigurator(sslHandler -> {
                            sslHandler.handshakeFuture().addListener(future -> {
                                if (future.isSuccess()) {
                                    SSLSession sslSession = sslHandler.engine().getSession();
                                    try {
                                        Certificate[] certificates = sslSession.getPeerCertificates();
                                        for (Certificate cert : certificates) {
                                            System.out.println("WebClient获取的证书:" + cert);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            });
                        }));

        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }
}

// 业务层使用示例
@Service
public class CertService {
    private final WebClient webClient;

    public CertService(WebClient webClient) {
        this.webClient = webClient;
    }

    public void fetchCert(String url) {
        webClient.get()
                .uri(url)
                .retrieve()
                .bodyToMono(String.class)
                .subscribe();
    }
}

关键说明

  • 底层都是通过SSLSession.getPeerCertificates()获取证书链,和HttpsURLConnection.getServerCertificates()逻辑一致
  • 响应式场景下优先使用subscribe()或链式调用,避免用block()阻塞线程
  • 如需对证书做校验、解析或持久化,可直接在握手回调中扩展业务逻辑

内容的提问来源于stack exchange,提问作者patsw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:11:05