# Java client with security

**URL:** <https://discuss.elastic.co/t/java-client-with-security/213505>\
**Category:** Elasticsearch\
**Created:** [January 2, 2020, 2:11am UTC](https://discuss.elastic.co/t/java-client-with-security/213505 "2020-01-02T02:11:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![wl105500396](https://avatars.discourse-cdn.com/v4/letter/w/e19adc/32.png) [@wl105500396](https://discuss.elastic.co/u/wl105500396)\
**Post date:** [January 2, 2020, 2:11am UTC](https://discuss.elastic.co/t/java-client-with-security/213505/1 "2020-01-02T02:11:43Z")

</div>

Hi there,

I'm now using ES java client to communicate with a secured ( x-pack ) es cluster, my java code is like below,

```
@Bean(destroyMethod = "close")
public RestHighLevelClient getRestHighLevelClient() {
	List<HttpHost> httpHosts = new ArrayList<>();
	esProperties.getNodes().forEach(esServer -> {
		httpHosts.add(new HttpHost(esServer.getHost(), esServer.getPort(), esServer.getProtocol()));
	});
	
	final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
	credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esProperties.getUserName(), esProperties.getPassword()));
	
	return new RestHighLevelClient(
		RestClient
			.builder(httpHosts.toArray(new HttpHost[httpHosts.size()]))
			.setHttpClientConfigCallback(
				httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
			)
			.setRequestConfigCallback(
				requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(5000).setSocketTimeout(60000)
			)
	);
}

```

but I'll get exception as below:

```
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.8.0_45]
	at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728) ~[na:1.8.0_45]
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:304) ~[na:1.8.0_45]
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) ~[na:1.8.0_45]
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1478) ~[na:1.8.0_45]
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212) ~[na:1.8.0_45]
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) ~[na:1.8.0_45]
	at sun.security.ssl.Handshaker$1.run(Handshaker.java:919) ~[na:1.8.0_45]
	at sun.security.ssl.Handshaker$1.run(Handshaker.java:916) ~[na:1.8.0_45]
	at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_45]
	at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1369) ~[na:1.8.0_45]
	at org.apache.http.nio.reactor.ssl.SSLIOSession.doRunTask(SSLIOSession.java:281) ~[httpcore-nio-4.4.11.jar:4.4.11]
	at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:339) ~[httpcore-nio-4.4.11.jar:4.4.11]
	... 9 common frames omitted
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) ~[na:1.8.0_45]
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.8.0_45]
	at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.8.0_45]
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) ~[na:1.8.0_45]
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:281) ~[na:1.8.0_45]
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136) ~[na:1.8.0_45]
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1465) ~[na:1.8.0_45]
	... 17 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

```

Can anyone help me out on this, thanks very much in advance ...

---

<div class="post-metadata">

**Author:** ![Armin\_Braun](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/armin_braun/32/20092_2.png) [@Armin\_Braun](https://discuss.elastic.co/u/Armin_Braun)\
**Post date:** [January 2, 2020, 7:04am UTC](https://discuss.elastic.co/t/java-client-with-security/213505/2 "2020-01-02T07:04:23Z")

</div>

Hi @wl105500396 ,

you will need to make a certificate that shares a valid chain with the certificate used by your ES cluster available to the Java client's JVM to fix the error pasted.

Either you import the ES cluster's certificate into the global Java keystore which should make it work automatically or better yet you do some thing like this:

1. Create a new keystore with the certificate in it.

```auto
keytool -importcert -file my_domain.crt -keystore my_keystore.jks -keypass password -storepass password

```

1. Use that keystore via initialization code like this as explained in [here](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/_encrypted_communication.html).

```auto
KeyStore truststore = KeyStore.getInstance("jks");
try (InputStream is = Files.newInputStream(keyStorePath)) {
    truststore.load(is, keyStorePass.toCharArray());
}
SSLContextBuilder sslBuilder = SSLContexts.custom()
    .loadTrustMaterial(truststore, null);
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);
        }
    });

```

Using a custom keystore instead of importing into the global `cacert` store has the advantage of continuing to work across Java runtime upgrades but both should work.

Hope that helps

---

<div class="post-metadata">

**Author:** ![wl105500396](https://avatars.discourse-cdn.com/v4/letter/w/e19adc/32.png) [@wl105500396](https://discuss.elastic.co/u/wl105500396)\
**Post date:** [January 3, 2020, 1:28am UTC](https://discuss.elastic.co/t/java-client-with-security/213505/3 "2020-01-03T01:28:39Z")

</div>

hi @Armin_Braun,

Thank you very much for your reply. I will have a try on this solution right away.

BTW, as you may have known that when we use curl command to communicate with es cluster, we are able to disable ssl verification by setting '-k' option, which will only verify user name and password.

Could I disable the ssl verification for the java client just like the curl command ?

Frankly, I'd rather prefer this one if it is workable.

Thank you.

---

<div class="post-metadata">

**Author:** ![Armin\_Braun](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/armin_braun/32/20092_2.png) [@Armin\_Braun](https://discuss.elastic.co/u/Armin_Braun)\
**Post date:** [January 3, 2020, 9:55am UTC](https://discuss.elastic.co/t/java-client-with-security/213505/4 "2020-01-03T09:55:22Z")

</div>

Hi @wl105500396

You could technically turn off the certificate validation yes (though I would rather recommend properly handling certificates and adding your own to the keystore from the security perspective :)).

But that said, below snippet should give you an `SSLContext` thet won't do any of the certificate chain verification I think.

```auto
                        SSLContext context = SSLContextBuilder.create().build();
                        context.init(
                            null, new TrustManager[] {new X509ExtendedTrustManager() {
                                @Override
                                public void checkClientTrusted (X509Certificate[] chain, String authType, Socket socket) {

                                }

                                @Override
                                public void checkServerTrusted (X509Certificate [] chain, String authType, Socket socket) {

                                }

                                @Override
                                public void checkClientTrusted (X509Certificate [] chain, String authType, SSLEngine engine) {

                                }

                                @Override
                                public void checkServerTrusted (X509Certificate [] chain, String authType, SSLEngine engine) {

                                }

                                @Override
                                public X509Certificate [] getAcceptedIssuers () {
                                    return null;
                                }

                                @Override
                                public void checkClientTrusted (X509Certificate [] certs, String authType) {
                                }

                                @Override
                                public void checkServerTrusted (X509Certificate [] certs, String authType) {
                                }

                            }},
                        new SecureRandom());

```

---

<div class="post-metadata">

**Author:** ![wl105500396](https://avatars.discourse-cdn.com/v4/letter/w/e19adc/32.png) [@wl105500396](https://discuss.elastic.co/u/wl105500396)\
**Post date:** [January 6, 2020, 7:10am UTC](https://discuss.elastic.co/t/java-client-with-security/213505/5 "2020-01-06T07:10:37Z")

</div>

Thank you @Armin_Braun

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [February 3, 2020, 7:10am UTC](https://discuss.elastic.co/t/java-client-with-security/213505/6 "2020-02-03T07:10:45Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
