ElasticSearch Java High RESTful Api Basic认证的问题
因公司Elasticsearch集群升级到7.1.1,需要使用用户名密码登入。并且设置的user、role等权限。那么之前直接访问的方式是不行的。需要使用认证的方式进行访问。
Elasticsearch的api非常的丰富。如:curl、python、java(多种)。下面展示curl、Python、Java high rest api实现Basic认证访问。
1. curl认证访问
# 需要指定 --user 用户名:密码
curl --user user:pwd -XGET http://es1.com/index_name/_count
2. python认证访问
from elasticsearch import Elasticsearch
# http_auth:表示http的basic认证
es = Elasticsearch(['es1','es2'], http_auth=('user', 'pwd'), port=9200)
print(es.count(index_name))
3.java high restful api认证访问
public class ESTest {
public static void main(String[] args) throws IOException {
final CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
RestClientBuilder clientBuilder = RestClient.builder(new HttpHost("es1", 9200));
clientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(provider);
}
});
RestHighLevelClient client = new RestHighLevelClient(clientBuilder);
CountRequest countRequest = new CountRequest();
countRequest.indices(index_name);
CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
System.out.println(countResponse.getCount());
client.close();
}
}
看起来没毛病是吧,实际上运行起来结果如下:
错误日志如下:
Exception in thread "main" ElasticsearchStatusException[Elasticsearch exception [type=security_exception, reason=action [indices:data/read/search] is unauthorized for user [anonymous_admin]]]
at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177)
at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1706)
at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1683)
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1446)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1403)
at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1373)
at org.elasticsearch.client.RestHighLevelClient.count(RestHighLevelClient.java:844)
at com.example.ESTest3.main(ESTest3.java:52)
Suppressed: org.elasticsearch.client.ResponseException: method [POST], host [http://es1:9200], URI [/xxx/_count?ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true], status line [HTTP/1.1 403 Forbidden]
{"error":{"root_cause":[{"type":"security_exception","reason":"action [indices:data/read/search] is unauthorized for user [anonymous_admin]"}],"type":"security_exception","reason":"action [indices:data/read/search] is unauthorized for user [anonymous_admin]"},"status":403}
at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:260)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:238)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:212)
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1433)
... 4 more
一开始看到这个问题,很疑惑,我使用用户名密码认证了啊,明明python,curl都行,为啥java不行,难道是我调用的api不对,有一遍遍的查api。后面实在是没办法,进行HttpProxy代理抓包,发现的确是没有Http的认证,在请求Headers中,没有Basic的Auth信息。最后,没办法,放弃了,就直接在Http中Headers手动根据用户名密码进行Base64转码设置进去,解决这个问题。
public class ESTest2 {
public static void main(String[] args) throws IOException {
String user = "user";
String pwd = "pwd";
String auth = Base64.encodeBase64String((user+":"+pwd).getBytes());
System.out.println(auth);
RestClientBuilder clientBuilder = RestClient.builder(new HttpHost("es1", 9200));
clientBuilder.setDefaultHeaders(new BasicHeader[]{new BasicHeader("Authorization", "Basic " + auth)});
RestHighLevelClient client = new RestHighLevelClient(clientBuilder);
CountRequest countRequest = new CountRequest();
countRequest.indices(index_name);
CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
System.out.println(countResponse.getCount());
client.close();
}
}