mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-23 20:42:11 +00:00
Allow SSL configuration with the Elasticsearch CA fingerprint.
Original Pull Request #2540 Closes #2539
This commit is contained in:
parent
17ecce4362
commit
406961c13b
@ -240,7 +240,7 @@ ClientConfiguration clientConfiguration = ClientConfiguration.builder()
|
||||
|
||||
<.> Define default headers, if they need to be customized
|
||||
<.> Use the builder to provide cluster addresses, set default `HttpHeaders` or enable SSL.
|
||||
<.> Optionally enable SSL.
|
||||
<.> Optionally enable SSL. There exist overloads of this function that can take a `SSLContext` or as an alternative the fingerprint of the certificate as it is output by Elasticsearch 8 on startup.
|
||||
<.> Optionally set a proxy.
|
||||
<.> Optionally set a path prefix, mostly used when different clusters a behind some reverse proxy.
|
||||
<.> Set the connection timeout.
|
||||
|
@ -5,6 +5,7 @@
|
||||
== New in Spring Data Elasticsearch 5.1
|
||||
|
||||
* Upgrade to Elasticsearch 8.7.0
|
||||
* Allow specification of the TLS certificate when connecting to an Elasticsearch 8 cluster
|
||||
|
||||
[[new-features.5-0-0]]
|
||||
== New in Spring Data Elasticsearch 5.0
|
||||
|
@ -20,7 +20,6 @@ import java.net.SocketAddress;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
@ -28,7 +27,6 @@ import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.springframework.data.elasticsearch.support.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Configuration interface exposing common client configuration properties for Elasticsearch clients.
|
||||
@ -122,6 +120,12 @@ public interface ClientConfiguration {
|
||||
*/
|
||||
Optional<SSLContext> getSslContext();
|
||||
|
||||
/**
|
||||
* @return the optional SHA-256 fingerprint of the self-signed http_ca.crt certificate output by Elasticsearch at
|
||||
* startup time.
|
||||
*/
|
||||
Optional<String> getCaFingerprint();
|
||||
|
||||
/**
|
||||
* Returns the {@link HostnameVerifier} to use. Can be {@link Optional#empty()} if not configured.
|
||||
*
|
||||
@ -250,6 +254,15 @@ public interface ClientConfiguration {
|
||||
* @return the {@link TerminalClientConfigurationBuilder}.
|
||||
*/
|
||||
TerminalClientConfigurationBuilder usingSsl(SSLContext sslContext, HostnameVerifier hostnameVerifier);
|
||||
|
||||
/**
|
||||
* Connect via https using a SSLContext that is build from the given certificate fingerprint.
|
||||
*
|
||||
* @param caFingerprint the SHA-256 fingerprint of the self-signed http_ca.crt certificate output by Elasticsearch
|
||||
* at startup time.
|
||||
* @return the {@link TerminalClientConfigurationBuilder}.
|
||||
*/
|
||||
TerminalClientConfigurationBuilder usingSsl(String caFingerprint);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,6 @@ import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
@ -33,7 +32,6 @@ import org.springframework.data.elasticsearch.client.ClientConfiguration.Termina
|
||||
import org.springframework.data.elasticsearch.support.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Default builder implementation for {@link ClientConfiguration}.
|
||||
@ -51,14 +49,15 @@ class ClientConfigurationBuilder
|
||||
private final List<InetSocketAddress> hosts = new ArrayList<>();
|
||||
private HttpHeaders headers = new HttpHeaders();
|
||||
private boolean useSsl;
|
||||
private @Nullable SSLContext sslContext;
|
||||
private @Nullable HostnameVerifier hostnameVerifier;
|
||||
@Nullable private SSLContext sslContext;
|
||||
@Nullable private String caFingerprint;
|
||||
@Nullable private HostnameVerifier hostnameVerifier;
|
||||
private Duration connectTimeout = Duration.ofSeconds(10);
|
||||
private Duration soTimeout = Duration.ofSeconds(5);
|
||||
private @Nullable String username;
|
||||
private @Nullable String password;
|
||||
private @Nullable String pathPrefix;
|
||||
private @Nullable String proxy;
|
||||
@Nullable private String username;
|
||||
@Nullable private String password;
|
||||
@Nullable private String pathPrefix;
|
||||
@Nullable private String proxy;
|
||||
private Supplier<HttpHeaders> headersSupplier = HttpHeaders::new;
|
||||
@Deprecated private final HttpClientConfigCallback httpClientConfigurer = httpClientBuilder -> httpClientBuilder;
|
||||
private final List<ClientConfiguration.ClientConfigurationCallback<?>> clientConfigurers = new ArrayList<>();
|
||||
@ -138,10 +137,20 @@ class ClientConfigurationBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerminalClientConfigurationBuilder usingSsl(String caFingerprint) {
|
||||
|
||||
Assert.notNull(caFingerprint, "caFingerprint must not be null");
|
||||
|
||||
this.useSsl = true;
|
||||
this.caFingerprint = caFingerprint;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.TerminalClientConfigurationBuilder#withDefaultHeaders(org.springframework.http.HttpHeaders)
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.TerminalClientConfigurationBuilder#withDefaultHeaders(org.springframework.http.HttpHeaders)
|
||||
*/
|
||||
@Override
|
||||
public TerminalClientConfigurationBuilder withDefaultHeaders(HttpHeaders defaultHeaders) {
|
||||
|
||||
@ -228,8 +237,12 @@ class ClientConfigurationBuilder
|
||||
headers.setBasicAuth(username, password);
|
||||
}
|
||||
|
||||
return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, pathPrefix,
|
||||
hostnameVerifier, proxy, httpClientConfigurer, clientConfigurers, headersSupplier);
|
||||
if (sslContext != null && caFingerprint != null) {
|
||||
throw new IllegalArgumentException("Either SSLContext or caFingerprint must be set, but not both");
|
||||
}
|
||||
|
||||
return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, caFingerprint, soTimeout, connectTimeout,
|
||||
pathPrefix, hostnameVerifier, proxy, httpClientConfigurer, clientConfigurers, headersSupplier);
|
||||
}
|
||||
|
||||
private static InetSocketAddress parse(String hostAndPort) {
|
||||
|
@ -42,19 +42,20 @@ class DefaultClientConfiguration implements ClientConfiguration {
|
||||
private final List<InetSocketAddress> hosts;
|
||||
private final HttpHeaders headers;
|
||||
private final boolean useSsl;
|
||||
private final @Nullable SSLContext sslContext;
|
||||
@Nullable private final SSLContext sslContext;
|
||||
@Nullable private final String caFingerprint;
|
||||
private final Duration soTimeout;
|
||||
private final Duration connectTimeout;
|
||||
private final @Nullable String pathPrefix;
|
||||
private final @Nullable HostnameVerifier hostnameVerifier;
|
||||
private final @Nullable String proxy;
|
||||
@Nullable private final String pathPrefix;
|
||||
@Nullable private final HostnameVerifier hostnameVerifier;
|
||||
@Nullable private final String proxy;
|
||||
private final HttpClientConfigCallback httpClientConfigurer;
|
||||
private final Supplier<HttpHeaders> headersSupplier;
|
||||
private final List<ClientConfigurationCallback<?>> clientConfigurers;
|
||||
|
||||
DefaultClientConfiguration(List<InetSocketAddress> hosts, HttpHeaders headers, boolean useSsl,
|
||||
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix,
|
||||
@Nullable HostnameVerifier hostnameVerifier, @Nullable String proxy,
|
||||
@Nullable SSLContext sslContext, @Nullable String caFingerprint, Duration soTimeout, Duration connectTimeout,
|
||||
@Nullable String pathPrefix, @Nullable HostnameVerifier hostnameVerifier, @Nullable String proxy,
|
||||
HttpClientConfigCallback httpClientConfigurer, List<ClientConfigurationCallback<?>> clientConfigurers,
|
||||
Supplier<HttpHeaders> headersSupplier) {
|
||||
|
||||
@ -62,6 +63,7 @@ class DefaultClientConfiguration implements ClientConfiguration {
|
||||
this.headers = headers;
|
||||
this.useSsl = useSsl;
|
||||
this.sslContext = sslContext;
|
||||
this.caFingerprint = caFingerprint;
|
||||
this.soTimeout = soTimeout;
|
||||
this.connectTimeout = connectTimeout;
|
||||
this.pathPrefix = pathPrefix;
|
||||
@ -92,6 +94,11 @@ class DefaultClientConfiguration implements ClientConfiguration {
|
||||
return Optional.ofNullable(this.sslContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getCaFingerprint() {
|
||||
return Optional.ofNullable(this.caFingerprint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<HostnameVerifier> getHostNameVerifier() {
|
||||
return Optional.ofNullable(this.hostnameVerifier);
|
||||
|
@ -19,6 +19,7 @@ import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||
import co.elastic.clients.transport.ElasticsearchTransport;
|
||||
import co.elastic.clients.transport.TransportOptions;
|
||||
import co.elastic.clients.transport.TransportUtils;
|
||||
import co.elastic.clients.transport.Version;
|
||||
import co.elastic.clients.transport.rest_client.RestClientOptions;
|
||||
import co.elastic.clients.transport.rest_client.RestClientTransport;
|
||||
@ -34,13 +35,7 @@ import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpRequestInterceptor;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpResponseInterceptor;
|
||||
import org.apache.http.*;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
@ -197,6 +192,10 @@ public final class ElasticsearchClients {
|
||||
}
|
||||
|
||||
builder.setHttpClientConfigCallback(clientBuilder -> {
|
||||
if (clientConfiguration.getCaFingerprint().isPresent()) {
|
||||
clientBuilder
|
||||
.setSSLContext(TransportUtils.sslContextFromCaFingerprint(clientConfiguration.getCaFingerprint().get()));
|
||||
}
|
||||
clientConfiguration.getSslContext().ifPresent(clientBuilder::setSSLContext);
|
||||
clientConfiguration.getHostNameVerifier().ifPresent(clientBuilder::setSSLHostnameVerifier);
|
||||
clientBuilder.addInterceptorLast(new CustomHeaderInjector(clientConfiguration.getHeadersSupplier()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user