This commit adds examples in our documentation for - An HLRC instance authenticating to an elasticsearch cluster using an elasticsearch token service access token or an API key - An HLRC instance connecting to an elasticsearch cluster that is setup for TLS on the HTTP layer when the CA certificate of the cluster is available either as a PEM file or a keystore - An HLRC instance connecting to an elasticsearch cluster that requires client authentication where the client key and certificate are available in a keystore Co-Authored-By: Lisa Cawley <lcawley@elastic.co>
This commit is contained in:
parent
46166b9b40
commit
81e7d926f6
|
@ -51,10 +51,14 @@ import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
|
|||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.util.Base64;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
|
@ -379,11 +383,11 @@ public class RestClientDocumentation {
|
|||
//end::rest-client-config-disable-preemptive-auth
|
||||
}
|
||||
{
|
||||
Path keyStorePath = Paths.get("");
|
||||
String keyStorePass = "";
|
||||
//tag::rest-client-config-encrypted-communication
|
||||
KeyStore truststore = KeyStore.getInstance("jks");
|
||||
try (InputStream is = Files.newInputStream(keyStorePath)) {
|
||||
Path trustStorePath = Paths.get("/path/to/truststore.p12");
|
||||
KeyStore truststore = KeyStore.getInstance("pkcs12");
|
||||
try (InputStream is = Files.newInputStream(trustStorePath)) {
|
||||
truststore.load(is, keyStorePass.toCharArray());
|
||||
}
|
||||
SSLContextBuilder sslBuilder = SSLContexts.custom()
|
||||
|
@ -400,5 +404,87 @@ public class RestClientDocumentation {
|
|||
});
|
||||
//end::rest-client-config-encrypted-communication
|
||||
}
|
||||
{
|
||||
//tag::rest-client-config-trust-ca-pem
|
||||
Path caCertificatePath = Paths.get("/path/to/ca.crt");
|
||||
CertificateFactory factory =
|
||||
CertificateFactory.getInstance("X.509");
|
||||
Certificate trustedCa;
|
||||
try (InputStream is = Files.newInputStream(caCertificatePath)) {
|
||||
trustedCa = factory.generateCertificate(is);
|
||||
}
|
||||
KeyStore trustStore = KeyStore.getInstance("pkcs12");
|
||||
trustStore.load(null, null);
|
||||
trustStore.setCertificateEntry("ca", trustedCa);
|
||||
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
|
||||
.loadTrustMaterial(trustStore, null);
|
||||
final SSLContext sslContext = sslContextBuilder.build();
|
||||
RestClient.builder(
|
||||
new HttpHost("localhost", 9200, "https"))
|
||||
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
|
||||
@Override
|
||||
public HttpAsyncClientBuilder customizeHttpClient(
|
||||
HttpAsyncClientBuilder httpClientBuilder) {
|
||||
return httpClientBuilder.setSSLContext(sslContext);
|
||||
}
|
||||
});
|
||||
//end::rest-client-config-trust-ca-pem
|
||||
}
|
||||
{
|
||||
String trustStorePass = "";
|
||||
String keyStorePass = "";
|
||||
//tag::rest-client-config-mutual-tls-authentication
|
||||
Path trustStorePath = Paths.get("/path/to/your/truststore.p12");
|
||||
Path keyStorePath = Paths.get("/path/to/your/keystore.p12");
|
||||
KeyStore trustStore = KeyStore.getInstance("pkcs12");
|
||||
KeyStore keyStore = KeyStore.getInstance("pkcs12");
|
||||
try (InputStream is = Files.newInputStream(trustStorePath)) {
|
||||
trustStore.load(is, trustStorePass.toCharArray());
|
||||
}
|
||||
try (InputStream is = Files.newInputStream(keyStorePath)) {
|
||||
keyStore.load(is, keyStorePass.toCharArray());
|
||||
}
|
||||
SSLContextBuilder sslBuilder = SSLContexts.custom()
|
||||
.loadTrustMaterial(trustStore, null)
|
||||
.loadKeyMaterial(keyStore, keyStorePass.toCharArray());
|
||||
final SSLContext sslContext = sslBuilder.build();
|
||||
RestClientBuilder builder = RestClient.builder(
|
||||
new HttpHost("localhost", 9200, "https"))
|
||||
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
|
||||
@Override
|
||||
public HttpAsyncClientBuilder customizeHttpClient(
|
||||
HttpAsyncClientBuilder httpClientBuilder) {
|
||||
return httpClientBuilder.setSSLContext(sslContext);
|
||||
}
|
||||
});
|
||||
//end::rest-client-config-mutual-tls-authentication
|
||||
}
|
||||
{
|
||||
//tag::rest-client-auth-bearer-token
|
||||
RestClientBuilder builder = RestClient.builder(
|
||||
new HttpHost("localhost", 9200, "http"));
|
||||
Header[] defaultHeaders =
|
||||
new Header[]{new BasicHeader("Authorization",
|
||||
"Bearer u6iuAxZ0RG1Kcm5jVFI4eU4tZU9aVFEwT2F3")};
|
||||
builder.setDefaultHeaders(defaultHeaders);
|
||||
//end::rest-client-auth-bearer-token
|
||||
}
|
||||
{
|
||||
//tag::rest-client-auth-api-key
|
||||
String apiKeyId = "uqlEyn8B_gQ_jlvwDIvM";
|
||||
String apiKeySecret = "HxHWk2m4RN-V_qg9cDpuX";
|
||||
String apiKeyAuth =
|
||||
Base64.getEncoder().encodeToString(
|
||||
(apiKeyId + ":" + apiKeySecret)
|
||||
.getBytes(StandardCharsets.UTF_8));
|
||||
RestClientBuilder builder = RestClient.builder(
|
||||
new HttpHost("localhost", 9200, "http"));
|
||||
Header[] defaultHeaders =
|
||||
new Header[]{new BasicHeader("Authorization",
|
||||
"ApiKey " + apiKeyAuth)};
|
||||
builder.setDefaultHeaders(defaultHeaders);
|
||||
//end::rest-client-auth-api-key
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,21 +64,75 @@ include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-disa
|
|||
--------------------------------------------------
|
||||
<1> Disable preemptive authentication
|
||||
|
||||
=== Other authentication methods
|
||||
|
||||
==== Elasticsearch Token Service tokens
|
||||
|
||||
If you want the client to authenticate with an Elasticsearch access token, set the relevant HTTP request header.
|
||||
If the client makes requests on behalf of a single user only, you can set the necessary `Authorization` header as a default header as shown
|
||||
in the following example:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-auth-bearer-token]
|
||||
--------------------------------------------------
|
||||
|
||||
==== Elasticsearch API keys
|
||||
|
||||
If you want the client to authenticate with an Elasticsearch API key, set the relevant HTTP request header.
|
||||
If the client makes requests on behalf of a single user only, you can set the necessary `Authorization` header as a default header as shown
|
||||
in the following example:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-auth-api-key]
|
||||
--------------------------------------------------
|
||||
|
||||
=== Encrypted communication
|
||||
|
||||
Encrypted communication can also be configured through the
|
||||
Encrypted communication using TLS can also be configured through the
|
||||
`HttpClientConfigCallback`. The
|
||||
https://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/apidocs/org/apache/http/impl/nio/client/HttpAsyncClientBuilder.html[`org.apache.http.impl.nio.client.HttpAsyncClientBuilder`]
|
||||
received as an argument exposes multiple methods to configure encrypted
|
||||
communication: `setSSLContext`, `setSSLSessionStrategy` and
|
||||
`setConnectionManager`, in order of precedence from the least important.
|
||||
The following is an example:
|
||||
|
||||
When accessing an Elasticsearch cluster that is setup for TLS on the HTTP layer, the client needs to trust the certificate that
|
||||
Elasticsearch is using.
|
||||
The following is an example of setting up the client to trust the CA that has signed the certificate that Elasticsearch is using, when
|
||||
that CA certificate is available in a PKCS#12 keystore:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-encrypted-communication]
|
||||
--------------------------------------------------
|
||||
|
||||
The following is an example of setting up the client to trust the CA that has signed the certificate that Elasticsearch is using, when
|
||||
that CA certificate is available as a PEM encoded file.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-trust-ca-pem]
|
||||
--------------------------------------------------
|
||||
|
||||
When Elasticsearch is configured to require client TLS authentication, for example when a PKI realm is configured, the client needs to provide
|
||||
a client certificate during the TLS handshake in order to authenticate. The following is an example of setting up the client for TLS
|
||||
authentication with a certificate and a private key that are stored in a PKCS#12 keystore.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-mutual-tls-authentication]
|
||||
--------------------------------------------------
|
||||
|
||||
If the client certificate and key are not available in a keystore but rather as PEM encoded files, you cannot use them
|
||||
directly to build an SSLContext. You must rely on external libraries to parse the PEM key into a PrivateKey instance. Alternatively, you
|
||||
can use external tools to build a keystore from your PEM files, as shown in the following example:
|
||||
|
||||
```
|
||||
openssl pkcs12 -export -in client.crt -inkey private_key.pem \
|
||||
-name "client" -out client.p12
|
||||
```
|
||||
|
||||
If no explicit configuration is provided, the http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores[system default configuration]
|
||||
will be used.
|
||||
|
||||
|
|
Loading…
Reference in New Issue