概述
Elasticsearch 7.9.0 开启了用户名密码校验,需要用户名密码登入。并且设置的user、role等权限。需要使用认证的方式进行访问。
application.yml 配置
# Elasticsearch
es:
schema: http # 协议
address: 192.168.6.89:9200 # IP:端口号
username: esuser #用户名
password: changeme #密码
connect-timeout: 5000 # 连接超时
socket-timeout: 10000 # socket 连接超时时间
connection-request-timeout: 5000 # 连接请求超时
max-connect-num: 100 # 最大连接数
max-connect-per-route: 100 # 最大路由连接数
pom.xml 依赖
<!-- ElasticSearch 高级客户端 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
ElasticSearchConfig 配置类
package com.demo.config;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
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 java.util.ArrayList;
import java.util.List;
/**
* 搜索引擎配置类
*
* @author lee
* @date 2022/5/31 15:40
*/
@Configuration
public class ElasticSearchConfig {
/**
* 集群地址,如果有多个,用"," 隔开
*/
@Value("${es.address}")
private String address;
/**
* 协议
*/
@Value("${es.schema}")
private String schema;
/**
* 用户名
*/
@Value("${es.username}")
private String userName;
/**
* 密码
*/
@Value("${es.password}")
private String password;
/**
* 连接超时时间
*/
@Value("${es.connect-timeout}")
private int connectTimeout;
/**
* Socket 连接超时时间
*/
@Value("${es.socket-timeout}")
private int socketTimeout;
/**
* 获取连接的超时时间
*/
@Value("${es.connection-request-timeout}")
private int connectionRequestTimeout;
/**
* 最大路连接数
*/
@Value("${es.max-connect-num}")
private int maxConnectNum;
/**
* 最大路由连接数
*/
@Value("${es.max-connect-per-route}")
private int maxConnectPerRoute;
@Bean
public RestHighLevelClient restHighLevelClient() {
String auth = Base64.encodeBase64String((userName + ":" + password).getBytes());
// 拆分地址
List<HttpHost> hostLists = new ArrayList<>();
String[] hostList = address.split(",");
for (String addr : hostList) {
String host = addr.split(":")[0];
String port = addr.split(":")[1];
hostLists.add(new HttpHost(host, Integer.parseInt(port), schema));
}
// 转换成 HttpHost数据
HttpHost[] httpHost = hostLists.toArray(new HttpHost[]{});
// 设置用户名和密码
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
RestClientBuilder builder = RestClient.builder(httpHost)
.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
});
// 异步连接延迟
builder.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(connectTimeout);
requestConfigBuilder.setSocketTimeout(socketTimeout);
requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeout);
return requestConfigBuilder;
});
// 设置 header
builder.setDefaultHeaders(new BasicHeader[]{
new BasicHeader("Authorization", "Basic" + auth)
});
return new RestHighLevelClient(builder);
}
可能出现异常
{
"error": {
"root_cause": [
{
"type": "security_exception",
"reason": "missing authentication credentials for REST request [/demo/_search]",
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
}
}
],
"type": "security_exception",
"reason": "missing authentication credentials for REST request [/demo/_search]",
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
}
},
"status": 401
}
解决方案
尝试删除代码
// 设置 header
builder.setDefaultHeaders(new BasicHeader[]{
new BasicHeader("Authorization", "Basic" + auth)
});
参考链接
【简书】解决ElasticSearch Java High RESTful Api Basic认证的问题
ps:如有错误,欢迎批评指正,谢谢!