在我之前的教程 “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 来进行展示:

   private static synchronized void makeConnection_https() throws CertificateException, IOException, 
    		NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        final CredentialsProvider credentialsProvider =
                new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials("elastic", "FW5S2hBXhCNZDZ7BX9O-"));

        Path caCertificatePath = Paths.get("/Users/liuxg/test/elasticsearch-8.1.2/config/certs/http_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();

        RestClientBuilder builder = RestClient.builder(
                        new HttpHost("localhost", 9200, "https"))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(
                            HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder.setSSLContext(sslContext)
                                .setDefaultCredentialsProvider(credentialsProvider);
                    }
                });

        RestClient restClient = builder.build();

        // Create the transport with a Jackson mapper
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());

        client = new ElasticsearchClient(transport);
        asyncClient = new ElasticsearchAsyncClient(transport);
    }

如上所示,我们需要修改账号 elastic 的密码以及证书的路径。一旦 client 及 asyncClient 被创建,那么我们就可以使用它们来进行操作。

使用 API key 来进行访问

我们创建如下的 makeConnection_token() 方法来进行连接:

    private static synchronized void makeConnection_token() throws CertificateException, IOException, 
    	NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        Path caCertificatePath = Paths.get("/Users/liuxg/test/elasticsearch-8.1.2/config/certs/http_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();

        RestClientBuilder builder = RestClient.builder(
                        new HttpHost("localhost", 9200, "https"))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(
                            HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder.setSSLContext(sslContext);
                    }
                });

//        String apiKeyId = "SY6uOoABwRrDJxOdlx78";
//        String apiKeySecret = "E8Ae8-FgScqT-nXCSBN0ew";
//        String apiKeyAuth =
//                Base64.getEncoder().encodeToString(
//                        (apiKeyId + ":" + apiKeySecret)
//                                .getBytes(StandardCharsets.UTF_8));
//        Header[] defaultHeaders =
//                new Header[]{new BasicHeader("Authorization",
//                        "ApiKey " + apiKeyAuth)};
//        builder.setDefaultHeaders(defaultHeaders);

        Header[] defaultHeaders =
                new Header[]{new BasicHeader("Authorization",
                        "ApiKey U1k2dU9vQUJ3UnJESnhPZGx4Nzg6RThBZTgtRmdTY3FULW5YQ1NCTjBldw==")};
        builder.setDefaultHeaders(defaultHeaders);

        RestClient restClient = builder.build();

        // Create the transport with a Jackson mapper
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());

        client = new ElasticsearchClient(transport);
        asyncClient = new ElasticsearchAsyncClient(transport);
    }

有关如何创建这个 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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐