一、问题场景

在Elasticsearch 6.5以上版本中提供了安全模式,开启安全模式后需要输入用户名和密码,同时使用ssl https方式才能连接集群进行相关操作。

二、解决方式1 - RestHighLevelClient方式

使用官方提供RestHighLevelClient作为客户端进行连接集群以及相关操作的实现。其中使用HttpHost类负责http请求,并在HttpHost类中将CredentialsProvider和SSLIOSessionStrategy配置参数类封装在自定义的SecuredHttpClientConfigCallback类配置请求连接参数。代码如下创建RestHighLevelClient

    public RestHighLevelClient restClient() {
        LOGGER.info("Elasticsearch init start ......");
        RestHighLevelClient restClient = null;
        try {
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY,
                    new UsernamePasswordCredentials(username, password));

            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE);
            restClient = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost(hostName, port, scheme))
                            .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                                    httpClientBuilder.disableAuthCaching();
                                    httpClientBuilder.setSSLStrategy(sessionStrategy);
                                    httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                                    return httpClientBuilder;
                                }
                            }));
        } catch (Exception e) {
            LOGGER.error("elasticsearch TransportClient create error!!", e);
        }
        return restClient;
    }
三、解决方式2 - Apache HttpClient 方式

使用httpclient方式访问https ES集群需要ssl认证和创建sslClient方式,代码如下:

//创建ssl client
public CloseableHttpClient sslClient() {
        LOGGER.info("HttpClient init start ......");
        CloseableHttpClient sslClient = null;
        // 用户认证提供者
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有证书,本地证书
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            sslClient = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultCredentialsProvider(credentialsProvider).build();
        } catch (Exception e) {
            LOGGER.error("HttpClient create error!!", e);
        }
        if (sslClient != null) {
            return sslClient;
        }
        return sslClient;
    }

总结:如果需要通过ElasticSearch安全模式的认证,需要注意两点:信任本地证书,也就是创建SSLContext  和 如果同时有账号密码认证,需要添加CredentialsProvider。

另外ElasticSearch也有通过安全证书连接的方式,大家可以查询ElasticSearch文档得到解决.

Logo

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

更多推荐