Reputation: 11
Context
I'm working on a project using Spring Boot 3.2.5 and the RestClient
library with powered with HttpExchange to create a declarative
REST http client. I have a problem with certs in my app. I'm at the stage of debugging, and trusting all certificates would be a big convenience.
The Problem
The challenge I'm facing is configuring RestClient
to trust all certificates. I've searched the documentation thoroughly, but haven't found anything specific on this. I understand it's not ideal for production, but for debugging purposes, it would be a huge time-saver.
My Attpempt:
I explored extending the ClientHttpRequestFactory
class to achieve this functionality. However, after looking at the decompiled library code, it seemed like a complex and error-prone approach. There's a lot of abstraction involved, and I wasn't confident about the potential side effects in production if something went wrong. Also it's either deeply hiddne, or there are not usable option to configure SSL/TLS in this way.
The Question
Given this scenario, how can I configure RestClient
in Spring Boot 3.2.5 to trust all certificates? I'd prefer to maintain a declarative approach using HttpServiceProxyFactory
and an interface for my API client.
Documentation for libraries: Spring RestClient, Declarative REST Client
Here is my current simplified code I'm using:
@Slf4j
@Configuration
public class FooClientConfig {
@Bean
public FooClient buildNativeClient(RestClient.Builder builder, RestClientSsl ssl, NativeProperties properties) {
// construct the base URL, even with protocol (https/https based on ssl prop)
var baseUrl = buildBaseUrl(...);
builder.baseUrl(baseUrl)
.defaultHeaders(httpHeaders -> httpHeaders.setBasicAuth(properties.getBasicAuth().getUsername(), properties.getBasicAuth().getPassword()));
if (properties.getSsl().isEnabled()) {
builder.apply(ssl.fromBundle(properties.getSsl().getBundle()));
}
var requestFactory = buildRequestFactory(properties.getProxy());
var restClient = builder
.requestFactory(requestFactory)
.build();
return HttpServiceProxyFactory
.builderFor(RestClientAdapter.create(restClient))
.build()
.createClient(FooClient.class);
}
public static String buildBaseUrl(boolean sslEnabled, @NotNull String host, Integer hostPort, String baseUrl){
val protocol = sslEnabled ? "https" : "http";
val port = hostPort != null ? ":" + hostPort: "";
return String.format("%s://%s%s%s", protocol, host, port, baseUrl);
}
public static @NotNull ClientHttpRequestFactory buildRequestFactory(@NotNull ProxyConfig proxyConfig) {
final var requestFactory = new SimpleClientHttpRequestFactory();
// If proxying is enabled
if (proxyConfig.isEnabled()) {
val socketAdress = new InetSocketAddress(proxyConfig.getAddress(), proxyConfig.getPort());
val proxy = new Proxy(proxyConfig.getSchema(), socketAdress);
requestFactory.setProxy(proxy);
}
return requestFactory;
}
}
// Interface defining the API client operations
public interface FooClient {
@GetExchange()
ResponseEntity<Response> handshake();
}
Upvotes: 1
Views: 849