saeedj
saeedj

Reputation: 2429

Spring boot connect to Elasticsearch with basic authentication

Overview:

I tried non-secure connection between API and my local elasticsearch and everything worked well. To do securing connection, I did the following steps to add xpack plugin on my elastic and used it in the api:

My code changes in elastic configurations:

@Bean
public TransportClient transportClient() throws UnknownHostException {
    Settings settings = Settings.builder()
        .put("cluster.name", clusterName)
        .put("xpack.security.user", "api:apipass")
        .build();
    try (TransportClient client = new PreBuiltXPackTransportClient(settings)
        .addTransportAddress(new TransportAddress(InetAddress.getByName(host), tcpPort))) {            
        String token = basicAuthHeaderValue("api", new SecureString("apipass".toCharArray()));
        client.filterWithHeader(Collections.singletonMap("Authorization", token))
            .prepareSearch().get();

        return client;
    }
}

Issue:

When trying to run the elastic query via application, the following exception will be raised:

Caused by: java.lang.IllegalStateException: transport client is closed
at org.elasticsearch.client.transport.TransportClientNodesService.execute(TransportClientNodesService.java:243) ~[elasticsearch-6.0.0.jar:6.0.0]
at org.elasticsearch.client.transport.TransportProxyClient.execute(TransportProxyClient.java:59) ~[elasticsearch-6.0.0.jar:6.0.0]
at org.elasticsearch.client.transport.TransportClient.doExecute(TransportClient.java:357) ~[elasticsearch-6.0.0.jar:6.0.0]
at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:405) ~[elasticsearch-6.0.0.jar:6.0.0]
at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:394) ~[elasticsearch-6.0.0.jar:6.0.0]
at org.elasticsearch.action.ActionRequestBuilder.execute(ActionRequestBuilder.java:46) ~[elasticsearch-6.0.0.jar:6.0.0]
at org.elasticsearch.action.ActionRequestBuilder.get(ActionRequestBuilder.java:53) ~[elasticsearch-6.0.0.jar:6.0.0]

I would appreciate if anyone could share their genuine solution with me to connect Spring boot application to elasticsearch with basic authentication?

Upvotes: 1

Views: 14909

Answers (3)

If you using <artifactId>spring-boot-starter-data-elasticsearch</artifactId> dependency you need specify username and password via Basic Authentication.

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;

@Configuration
@EnableElasticsearchRepositories(basePackages = "yourpackage.domain.elastic")
public class ElasticConfig {
    @Value("${elasticsearch.host}")
    private String host;
    @Value("${elasticsearch.username}")
    private String username;
    @Value("${elasticsearch.password}")
    private String password;

    @Bean
    public RestHighLevelClient client() {
        ClientConfiguration clientConfiguration
                = ClientConfiguration.builder()
                .connectedTo(host)
                .withBasicAuth(username, password) // put your credentials
                .build();
        return RestClients.create(clientConfiguration).rest();
    }

    @Bean
    public ElasticsearchOperations elasticsearchTemplate() {
        return new ElasticsearchRestTemplate(client());
    }
}

Upvotes: 6

Tiago Pinto
Tiago Pinto

Reputation: 23

Remove the transport client from the Try-with-resources, the client is being closed when you leave the "try". You may have an error from Sonar or similar code reviewer. That was the solution I found.

Upvotes: 1

Phan Nguyen
Phan Nguyen

Reputation: 68

    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials("username", "password"));

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

    final RestClient restClient = builder.build();
    final Response result = restClient.performRequest("GET", "_index/blahblah",
                Collections.emptyMap());

@saeedj: I followed https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.x/_basic_authentication.html

You can try it :)

Upvotes: 1

Related Questions