Elasticsearch:使用 Elasticsearch Java client 8.0 来连接带有 HTTPS 的集群

2,254 阅读3分钟

在我之前的教程 “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