Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9a70591

Browse files
l-trottawilkinsona
authored andcommitted
Add support for Elasticsearch API-key-based authentication
See gh-46167 Signed-off-by: Laura Trotta <laura.trotta@elastic.co>
1 parent 79d409a commit 9a70591

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

‎module/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchConnectionDetails.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ public interface ElasticsearchConnectionDetails extends ConnectionDetails {
5757
return null;
5858
}
5959

60+
/**
61+
* APIKey for authentication with Elasticsearch.
62+
* @return APIKey for authentication with Elasticsearch or {@code null}
63+
*/
64+
default @Nullable String getAPIKey() {
65+
return null;
66+
}
67+
6068
/**
6169
* Prefix added to the path of every request sent to Elasticsearch.
6270
* @return prefix added to the path of every request sent to Elasticsearch or

‎module/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchProperties.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ public class ElasticsearchProperties {
4848
* Password for authentication with Elasticsearch.
4949
*/
5050
private @Nullable String password;
51+
/**
52+
* APIKey for authentication with Elasticsearch.
53+
*/
54+
private @Nullable String APIKey;
5155

5256
/**
5357
* Connection timeout used when communicating with Elasticsearch.
@@ -95,6 +99,14 @@ public void setPassword(@Nullable String password) {
9599
this.password = password;
96100
}
97101

102+
public @Nullable String getAPIKey() {
103+
return this.APIKey;
104+
}
105+
106+
public void setAPIKey(@Nullable String APIKey) {
107+
this.APIKey = APIKey;
108+
}
109+
98110
public Duration getConnectionTimeout() {
99111
return this.connectionTimeout;
100112
}

‎module/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientConfigurations.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
3737
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
3838
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
39+
import org.apache.hc.core5.http.Header;
3940
import org.apache.hc.core5.http.HttpHost;
41+
import org.apache.hc.core5.http.message.BasicHeader;
4042
import org.apache.hc.core5.reactor.IOReactorConfig;
4143
import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
4244
import org.apache.hc.core5.util.Timeout;
@@ -67,6 +69,7 @@
6769
* @author Moritz Halbritter
6870
* @author Andy Wilkinson
6971
* @author Phillip Webb
72+
* @author Laura Trotta
7073
*/
7174
class ElasticsearchRestClientConfigurations {
7275

@@ -99,6 +102,11 @@ Rest5ClientBuilder elasticsearchRestClientBuilder(ElasticsearchConnectionDetails
99102
.stream()
100103
.map((node) -> new HttpHost(node.protocol().getScheme(), node.hostname(), node.port()))
101104
.toArray(HttpHost[]::new));
105+
if (connectionDetails.getAPIKey() != null) {
106+
builder.setDefaultHeaders(new Header[]{
107+
new BasicHeader("Authorization", "ApiKey " + connectionDetails.getAPIKey()),
108+
});
109+
}
102110
builder.setHttpClientConfigCallback((httpClientBuilder) -> builderCustomizers.orderedStream()
103111
.forEach((customizer) -> customizer.customize(httpClientBuilder)));
104112
builder.setConnectionManagerCallback((connectionManagerBuilder) -> builderCustomizers.orderedStream()
@@ -275,6 +283,11 @@ public List<Node> getNodes() {
275283
return this.properties.getPassword();
276284
}
277285

286+
@Override
287+
public @Nullable String getAPIKey() {
288+
return this.properties.getAPIKey();
289+
}
290+
278291
@Override
279292
public @Nullable String getPathPrefix() {
280293
return this.properties.getPathPrefix();

‎module/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfigurationTests.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.time.Duration;
2020
import java.util.ArrayList;
2121
import java.util.List;
22+
import java.util.Optional;
2223

2324
import co.elastic.clients.transport.rest5_client.low_level.Node;
2425
import co.elastic.clients.transport.rest5_client.low_level.Rest5Client;
@@ -33,6 +34,7 @@
3334
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
3435
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
3536
import org.apache.hc.core5.function.Resolver;
37+
import org.apache.hc.core5.http.Header;
3638
import org.apache.hc.core5.http.HttpHost;
3739
import org.apache.hc.core5.http.config.Registry;
3840
import org.apache.hc.core5.util.Timeout;
@@ -47,6 +49,7 @@
4749
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
4850
import org.springframework.context.annotation.Bean;
4951
import org.springframework.context.annotation.Configuration;
52+
import org.springframework.web.client.RestClient;
5053

5154
import static org.assertj.core.api.Assertions.assertThat;
5255
import static org.mockito.BDDMockito.then;
@@ -62,6 +65,7 @@
6265
* @author Andy Wilkinson
6366
* @author Moritz Halbritter
6467
* @author Phillip Webb
68+
* @author Laura Trotta
6569
*/
6670
class ElasticsearchRestClientAutoConfigurationTests {
6771

@@ -134,6 +138,25 @@ void configureUriWithNoScheme() {
134138
});
135139
}
136140

141+
@Test
142+
void configureUriWithAPiKey() {
143+
this.contextRunner.withPropertyValues("spring.elasticsearch.uris=http://user@localhost:9200","spring.elasticsearch.apikey=some-apiKey").run((context) -> {
144+
Rest5Client client = context.getBean(Rest5Client.class);
145+
assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString))
146+
.containsExactly("http://localhost:9200");
147+
assertThat(client)
148+
.extracting("defaultHeaders", InstanceOfAssertFactories.list(Header.class))
149+
.satisfies(( defaultHeaders) -> {
150+
Optional<? extends Header> authHeader = defaultHeaders.stream()
151+
.filter(x -> x.getName().equals("Authorization"))
152+
.findFirst();
153+
assertThat(authHeader).isPresent();
154+
assertThat(authHeader.get().getValue()).isEqualTo("ApiKey some-apiKey");
155+
});
156+
});
157+
}
158+
159+
137160
@Test
138161
void configureUriWithUsernameOnly() {
139162
this.contextRunner.withPropertyValues("spring.elasticsearch.uris=http://user@localhost:9200").run((context) -> {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /