Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Cloud Gateway Pass Client Certificate Information

I am trying to forward client certificate information from Spring Cloud Gateway to microservices behind it. I modified the Netty config and it is successfully requesting a client cert from the client, but I don't see it forwarding it to the microservice behind it. In Apache we used to use +ExportCertData which populated a handful of headers with the client certificate DN, validity time, etc. Does Spring Cloud Gateway have any out of the box functionality like this?

I found these 2 questions which seem similar, but neither had very explicit answers. spring cloud gateway forward client certificate and Does anyone have a simple example of implementing x509 mutual authentication in Spring Cloud Gateway/Spring WebFlux?

like image 407
cstack Avatar asked Feb 23 '26 15:02

cstack


1 Answers

After playing with it for a while, changing something on the Netty HttpClient did not seem to be right because as far as I could tell it did not know anything about where the request came from. However I found that the filter chain had all the information I needed, so I put in a custom GlobalFilter which adds the certificate information to the header like what Apache does.

public class ClientSSLToHeaderFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { 
        ServerHttpRequest req = exchange.getRequest();
        SslInfo info = req.getSslInfo();
        if(info != null) {
            X509Certificate[] certs = info.getPeerCertificates();
            if(certs != null && certs.length > 0) {

                ServerHttpRequest request = exchange.getRequest().mutate()
                        .headers(httpHeaders -> {
                            try {
                                certs[0].checkValidity();
                                String encodedCert = new String(Base64.getEncoder().encode(certs[0].getEncoded())); 
                                httpHeaders.add("SSL_CLIENT_CERT", encodedCert); 
                                httpHeaders.add("SSL_CLIENT_VERIFY", "success");
                            } catch(CertificateEncodingException | CertificateExpiredException
                                    | CertificateNotYetValidException e) {
                                // TODO Auto-generated catch block
                                log.log(Level.ERROR, e, e);
                            }

                        }).build();
                return  chain.filter(exchange.mutate().request(request).build());
            }

        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}
like image 154
cstack Avatar answered Feb 27 '26 03:02

cstack



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!