Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebClient get SSL/TLS certificates

java.net has a simple getServerCertificates in its API (example follows). I was looking for a similar operation in reactor-netty, and if not there, in any other reactive API for spring-boot/webflux/HttpClient.

This operation (client reads certificate) does not seem possible in reactor-netty. Is it? If it isn't is there an alternative method in another spring-boot component to do this?

package com.example.readCertificate.service;

import java.net.URL;
import java.securiiity.cert.Certificate;
import javax.net.ssl.HttpsURLConnection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class ShowCert {
    private Logger logger = LogManager.getLogger();

    public void showCert(String url) {
        try {
            URL destinationURL = new URL(url);
            HttpsURLConnection connection = (HttpsURLConnection) destinationURL.openConnection();
            connection.connect();
            Certificate[] certificates = connection.getServerCertificates();
            for (Certificate certificate : certificates) {
                logger.info("certificate is:" + certificate);
            }
        } catch (Exception e) {
            logger.error(e);
        }
    }

}
like image 437
patsw Avatar asked Dec 19 '25 18:12

patsw


1 Answers

In WebClient from Spring WebFlux we usually use netty as backend. We provide a bean ReactorClientHttpConnector in which we create netty http-client.

For handling SSL netty uses handler within the channel pipeline.

Here I'm putting a callback to event doOnConnected() and accesing the SSL handler and SSLSession.

SSLSession provides methods getPeerCertificates(), getLocalCertificates() , so we can get access to certificates here.

@Bean
public ReactorClientHttpConnector reactorClientHttpConnector() {
    return new ReactorClientHttpConnector(
            HttpClient.create()
                    .doOnConnected(connection -> {
                        ChannelPipeline pipeline = connection.channel().pipeline();
                            
                        Optional.ofNullable(pipeline)
                                .map(p -> p.get(SslHandler.class))
                                .map(SslHandler::engine)
                                .map(SSLEngine::getSession)
                                .ifPresent(sslSession -> {
                                    try {
                                        Certificate[] peerCertificates = sslSession.getPeerCertificates();
                                        if (Objects.nonNull(peerCertificates)) {
                                            Stream.of(peerCertificates)
                                                    .forEach(System.out::println);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                });
                    })
    );
}

And create your WebClient:

@Bean
public WebClient httpsClient() {
    return WebClient.builder()
            .clientConnector(reactorClientHttpConnector())
            .baseUrl("https://secured-resource.com)
            .build();
}

Then while making http-call with this httpsClient bean you should see the results in your console

like image 89
kerbermeister Avatar answered Dec 21 '25 06:12

kerbermeister



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!