在我之前的教程 “Elasticsearch:使用最新的 Elasticsearch Java client 8.0 来创建索引并搜索”,我详述了如何使用 Java client 8.0 来连接一个 Elasticsearch 8.x 的集群。在那个例子中,我们的 Elasticsearch 集群是不带有 HTTPS 的安全设置的。在 Elasticsearch 8.x 的安装中,HTTPS 的配置是默认的,而且它的证书是自签名的。我们该如何修改我们的 Java 客户端代码来进行含有证书的连接呢?
如果你还没有安装好自己的 Elasticsearch 集群,你可以参考我之前的文章 “如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch” 来进行安装。
在接下来的示例中,我将使用 Elasticsearch 8.1.1 来进行展示。为了大家更好地理解我下面的代码,我把代码放到 github 上。你可以通过如下的命令来进行下载:
git clone https://github.com/liu-xiao-guo/elasticsearchjava-search8-https
在这篇文章中,我着重来讲一下和 Elasticsearch 的连接部分。其它的展示和之前的文章 “Elasticsearch:使用最新的 Elasticsearch Java client 8.0 来创建索引并搜索” 类似。
使用 Elasticsearch Java client 8.0 来连接带有 HTTPS 的集群
使用 Elasticsearch Java client 8.0 来连接带有 HTTPS 的集群_哔哩哔哩_bilibili
使用用户名及密码来进行连接
我们可以使用自己账号的用户名及密码来进行连接。在我们的展示中,我使用超级用户 elastic 来进行展示:
1. private static synchronized void makeConnection_https() throws CertificateException, IOException,
2. NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
3. final CredentialsProvider credentialsProvider =
4. new BasicCredentialsProvider();
5. credentialsProvider.setCredentials(AuthScope.ANY,
6. new UsernamePasswordCredentials("elastic", "FW5S2hBXhCNZDZ7BX9O-"));
8. Path caCertificatePath = Paths.get("/Users/liuxg/test/elasticsearch-8.1.2/config/certs/http_ca.crt");
9. CertificateFactory factory =
10. CertificateFactory.getInstance("X.509");
11. Certificate trustedCa;
12. try (InputStream is = Files.newInputStream(caCertificatePath)) {
13. trustedCa = factory.generateCertificate(is);
14. }
15. KeyStore trustStore = KeyStore.getInstance("pkcs12");
16. trustStore.load(null, null);
17. trustStore.setCertificateEntry("ca", trustedCa);
18. SSLContextBuilder sslContextBuilder = SSLContexts.custom()
19. .loadTrustMaterial(trustStore, null);
20. final SSLContext sslContext = sslContextBuilder.build();
22. RestClientBuilder builder = RestClient.builder(
23. new HttpHost("localhost", 9200, "https"))
24. .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
25. @Override
26. public HttpAsyncClientBuilder customizeHttpClient(
27. HttpAsyncClientBuilder httpClientBuilder) {
28. return httpClientBuilder.setSSLContext(sslContext)
29. .setDefaultCredentialsProvider(credentialsProvider);
30. }
31. });
33. RestClient restClient = builder.build();
35. // Create the transport with a Jackson mapper
36. ElasticsearchTransport transport = new RestClientTransport(
37. restClient, new JacksonJsonpMapper());
39. client = new ElasticsearchClient(transport);
40. asyncClient = new ElasticsearchAsyncClient(transport);
41. }
如上所示,我们需要修改账号 elastic 的密码以及证书的路径。一旦 client 及 asyncClient 被创建,那么我们就可以使用它们来进行操作。
使用 API 可以来进行访问
我们创建如下的 makeConnection_token() 方法来进行连接:
1. private static synchronized void makeConnection_token() throws CertificateException, IOException,
2. NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
3. Path caCertificatePath = Paths.get("/Users/liuxg/test/elasticsearch-8.1.2/config/certs/http_ca.crt");
4. CertificateFactory factory =
5. CertificateFactory.getInstance("X.509");
6. Certificate trustedCa;
7. try (InputStream is = Files.newInputStream(caCertificatePath)) {
8. trustedCa = factory.generateCertificate(is);
9. }
10. KeyStore trustStore = KeyStore.getInstance("pkcs12");
11. trustStore.load(null, null);
12. trustStore.setCertificateEntry("ca", trustedCa);
13. SSLContextBuilder sslContextBuilder = SSLContexts.custom()
14. .loadTrustMaterial(trustStore, null);
15. final SSLContext sslContext = sslContextBuilder.build();
17. RestClientBuilder builder = RestClient.builder(
18. new HttpHost("localhost", 9200, "https"))
19. .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
20. @Override
21. public HttpAsyncClientBuilder customizeHttpClient(
22. HttpAsyncClientBuilder httpClientBuilder) {
23. return httpClientBuilder.setSSLContext(sslContext);
24. }
25. });
27. // String apiKeyId = "SY6uOoABwRrDJxOdlx78";
28. // String apiKeySecret = "E8Ae8-FgScqT-nXCSBN0ew";
29. // String apiKeyAuth =
30. // Base64.getEncoder().encodeToString(
31. // (apiKeyId + ":" + apiKeySecret)
32. // .getBytes(StandardCharsets.UTF_8));
33. // Header[] defaultHeaders =
34. // new Header[]{new BasicHeader("Authorization",
35. // "ApiKey " + apiKeyAuth)};
36. // builder.setDefaultHeaders(defaultHeaders);
38. Header[] defaultHeaders =
39. new Header[]{new BasicHeader("Authorization",
40. "ApiKey U1k2dU9vQUJ3UnJESnhPZGx4Nzg6RThBZTgtRmdTY3FULW5YQ1NCTjBldw==")};
41. builder.setDefaultHeaders(defaultHeaders);
43. RestClient restClient = builder.build();
45. // Create the transport with a Jackson mapper
46. ElasticsearchTransport transport = new RestClientTransport(
47. restClient, new JacksonJsonpMapper());
49. client = new ElasticsearchClient(transport);
50. asyncClient = new ElasticsearchAsyncClient(transport);
51. }
有关如何创建这个 API key,你可以参阅我之前的文章 “Elasticsearch:创建 API key 接口访问 Elasticsearch”。如果你不想手动来创建,那么你可以使用如下的 Kibana UI 来创建:
其它的操作和之前的文章介绍的是一样的。这里就不再累述了。
参考:
【1】Other authentication methods | Elasticsearch Java API Client [8.1] | Elastic
【2】Encrypted communication | Elasticsearch Java API Client [8.1] | Elastic