elasticsearch-6.3 之前版本 设置密码认证
elasticsearch 6.3版本之前的添加认证需安装x-pack插件,6.3之后貌似去掉了这个。
1、安装x-pack
先切换到elastic用户下,在执行以下命令
$cd /data/elasticsearch-6.2.4 --进到elasticsearch的安装目录 $./bin/elasticsearch-plugin install x-pack
2、设置密码:
$cd /data/elasticsearch-6.2.4/bin/x-pack $./setup-passwords interactive
会对elasticsearch、logstash、kibana分别设置登录密码(默认es用户名为elastic,logstash用户名为logstash_system,kibana用户名为kibana)
3、设置elasticsearch配置文件
$vim /data/elasticsearch-6.2.4/config/elasticsearch.yml --添加如下三行 http.cors.enabled: true http.cors.allow-origin: '*' http.cors.allow-headers: Authorization,X-Requested-With,Content-Length,Content-Type
配置完重启下elasticsearch服务
4、测试
[elastic@data-backup elasticsearch-6.2.4]$curl http://10.163.19.231:9600 --不用密码访问,会报错 {"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication token for REST request [/]","header": {"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}}],"type":"security_exception","reason":"missing authentication token for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}},"status":401} [elastic@data-backup elasticsearch-6.2.4]$curl http://10.163.19.231:9600 -u elastic:elastic123 --用刚才新加的用户密码访问,能正常返回数据(elastic:用户名,elastic123:密码) { "name" : "eR3qSni", "cluster_name" : "elasticsearch", "cluster_uuid" : "pQbnNW7jRgmzbqvW7n2I5Q", "version" : { "number" : "6.2.4", "build_hash" : "ccec39f", "build_date" : "2018-04-12T20:37:28.497551Z", "build_snapshot" : false, "lucene_version" : "7.2.1", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" }
5、 添加自定义角色:
添加角色接口为:POST /_xpack/security/role/
下面添加一个超级管理员角色为例:
[elastic@data-backup elasticsearch-6.2.4]$ curl -XPOST -H 'Content-type: application/json' -u elastic:elastic123 'http://10.163.19.231:9600/_xpack/security/role/admin?pretty' -d '{
"run_as":["elastic"],
"cluster":["all"],
"indices":[
{
"names":["*"],
"privileges":["all"]
}
]
}'
{
"role" : {
"created" : true
}
}
[elastic@data-backup elasticsearch-6.2.4]$ curl -XGET -H 'Content-type: application/json' -u elastic:elastic123 'http://10.163.19.231:9600/_xpack/security/role/admin?pretty'
{
"admin" : {
"cluster" : [
"all"
],
"indices" : [
{
"names" : [
"*"
],
"privileges" : [
"all"
]
}
],
"run_as" : [
"elastic"
],
"metadata" : { },
"transient_metadata" : {
"enabled" : true
}
}
}
6、添加自定义用户:
添加用户接口为:POST/_xpack/security/user/
下面以添加一个test用户并添加至admin角色为例:
注:这里要注意的是用户密码最好不要有"$" "!"之类的字符,这样有可能会导致密码认证不成功,其他字符测试过暂时没问题(具体原因不详,反正我遇到过这个坑)
[elastic@data-backup elasticsearch-6.2.4]$ curl -XGET -H 'Content-type: application/json' -u test:Test123654% 'http://10.163.19.231:9600/_cat/indices?pretty' green open .monitoring-es-6-2019.09.17 J1K2XG1eTXqw0GHSOH5Gwg 1 0 848 104 846.9kb 846.9kb green open .watches qHj5owowRC-3DeK8DaLD-g 1 0 6 0 47.8kb 47.8kb green open .triggered_watches 2pm3BwCnTaKgyzl39eFpUw 1 0 0 0 5.1kb 5.1kb yellow open monitor yFnfztziSguTq9VsfSANpw 5 1 48 0 226.7kb 226.7kb green open .watcher-history-7-2019.09.17 uz6RA_8vRraHHLAitWKtAw 1 0 74 0 259.8kb 259.8kb green open .monitoring-alerts-6 ZPTqnNVOQ5GlUK1ncXNQDQ 1 0 2 0 18.1kb 18.1kb yellow open track AqSGAZnAQE2NGvZXlp9zcw 5 1 1343729 175384 201mb 201mb green open .security-6 83fAslPbQDSGbGWfhiMAXA 1 0
密码字符测试的部分截图:(这里用到的修改密码在下面有讲解)
7、修改用户密码:
修改密码需要使用超级管理员权限即elastic用户,接口为:POST /_xpack/security/user/要修改密码的用户名/_password
curl参数含义如下:
-XPOST 使用post方法传递参数
-H 指定http协议的header信息
-u 指定用于认证的用户信息,用户名与密码使用冒号分隔
-d 指定具体要传递的参数信息
例如:修改martin用户的密码为:dxm1234%
[elastic@data-backup elasticsearch-6.2.4]$curl -XPOST -H 'Content-type: application/json' -u elastic:elastic123 'http://10.163.19.231:9600/_xpack/security/user/martin/_password?pretty' -d '{"password": "dxm1234%"}'
修改密码后访问正常则说明修改成功,否则可能报错401
二、JAVA API
ES的JAVA API很多,这里介绍一个Java High Level REST Client,每个版本变化较大,这里以6.3.2来演示。
(一)客户端配置
pom文件:
<dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>transport-netty4-client</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-elasticsearch</artifactId> <version>${spring.data.elasticsearch.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <!-- es升级需要依赖的 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>${elasticsearch.version}</version> </dependency>
配置文件
elasticsearch: clientIps: 172.20.10.6 # ES网关地址,实际地址在ES实例概览中查看,注意至少配置两个网关地址 httpPort: 9200 # ES网关端口 username: elastic password: 123456
配置客户端:下面提供了使用用户名密码和不使用用户名密码两个Bean,可以任选其一
@Configuration public class ElasticSearchClientConfig { @Value("${elasticsearch.clientIps}") private String clientIps; @Value("${elasticsearch.httpPort}") private int httpPort; @Value("${elasticsearch.username}") private String username; @Value("${elasticsearch.password}") private String password; private HttpHost[] getHttpHosts(String clientIps, int esHttpPort) { String[] clientIpList = clientIps.split(","); HttpHost[] httpHosts = new HttpHost[clientIpList.length]; for (int i = 0; i < clientIpList.length; i++) { httpHosts[i] = new HttpHost(clientIpList[i], esHttpPort, "http"); } return httpHosts; } /** * 创建带HTTP Basic Auth认证rest客户端 */ @Bean public RestHighLevelClient restHighLevelClient() { CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); return new RestHighLevelClient(RestClient.builder(getHttpHosts(clientIps, httpPort)).setHttpClientConfigCallback((HttpAsyncClientBuilder httpAsyncClientBuilder) -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider))); } //不带用户名密码验证 //@Bean public RestHighLevelClient restClient() { return new RestHighLevelClient(RestClient.builder(getHttpHosts(clientIps, httpPort))); } }
(二)索引操作
添加索引
@Test public void creatIndex() throws Exception{ Map<String, Object> properties = new HashMap<>(); Map<String, Object> orderIdIndex = new HashMap<>(); orderIdIndex.put("type", "long"); orderIdIndex.put("store", true); orderIdIndex.put("index", true); properties.put("orderId", orderIdIndex); Map<String, Object> orderNameIndex = new HashMap<>(); orderNameIndex.put("type", "text"); orderNameIndex.put("store", true); orderNameIndex.put("index", true); properties.put("orderName", orderNameIndex); Map<String, Object> content = new HashMap<>(); content.put("type", "text"); content.put("store", true); content.put("index", true); properties.put("content", content); Map<String, Object> mapping = new HashMap<>(); mapping.put("properties", properties); CreateIndexRequest request = new CreateIndexRequest(INDEX); request.settings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 2).build()); request.mapping(TYPE, new Gson().toJson(mapping), XContentType.JSON); //request.mapping(mapping); CreateIndexResponse response = restHighLevelClient.indices().create(request); log.info("response====================={}", new Gson().toJson(response)); }
删除索引
@Test public void deleteIndex() throws Exception{ DeleteIndexRequest request = new DeleteIndexRequest(INDEX); DeleteIndexResponse response = restHighLevelClient.indices().delete(request); log.info("response====================={}", new Gson().toJson(response)); }
(三)数据操作
1、添加数据,添加索引可以使用Json格式、Map格式、XContentBuilder格式等,具体如下所示:
@Test public void saveDataByJson() throws Exception{ OrderInfo orderInfo = OrderInfo.builder().orderId(12345).orderName("测试12345的订单").content("的撒出手大方【平时都i法第四u发").build(); IndexRequest request = new IndexRequest(INDEX, TYPE, String.valueOf(orderInfo.getOrderId())); request.source(new Gson().toJson(orderInfo), XContentType.JSON); this.save(request); } @Test public void saveDataBMap() throws Exception{ Map<String, Object> jsonMap = new HashMap<>(); jsonMap.put("orderId", 11111); jsonMap.put("orderName", "1111的订单"); jsonMap.put("content", "破欸俗人伟大撒打发的"); IndexRequest request = new IndexRequest(INDEX,TYPE, jsonMap.get("orderId").toString()).source(jsonMap); this.save(request); } @Test public void saveDataByContentBuild() throws Exception{ XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject(); builder.field("orderId",2222); builder.field("orderName", "2222的订单"); builder.field("content", "送iu恶意然后我i和拉票;萨拉宽度"); builder.endObject(); IndexRequest request = new IndexRequest(INDEX, TYPE, "2222").source(builder); this.save(request); } @Test public void saveDataByObject() throws Exception{ XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject(); builder.field("orderId",2222); builder.field("orderName", "2222的订单"); builder.field("content", "送iu恶意然后我i和拉票;萨拉宽度"); builder.endObject(); IndexRequest request = new IndexRequest(INDEX, TYPE, "3333").source( "orderId",3333,"orderName", "3333的订单","content", "laisuyeiluqwgkjhgkjsgd" ); this.save(request); } private boolean save(IndexRequest request) throws Exception{ IndexResponse response = restHighLevelClient.index(request); log.info("response====================={}", new Gson().toJson(response)); if (response.status().getStatus() == 200) { return true; } return false; }
2、删除数据
@Test public void deleteData() throws Exception{ DeleteRequest request = new DeleteRequest(INDEX,TYPE,"2222"); DeleteResponse response = restHighLevelClient.delete(request); RestStatus restStatus = response.status(); }
3、获取数据
@Test public void getIncludeData() throws Exception{ GetRequest request = new GetRequest(INDEX, TYPE, "11111"); String[] includes = new String[]{"content", "修改"}; String[] excludes = Strings.EMPTY_ARRAY; FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); request.fetchSourceContext(fetchSourceContext); this.getData(request); } private void getData(GetRequest request) throws Exception{ GetResponse response = restHighLevelClient.get(request); log.info("response====================={}", new Gson().toJson(response)); Map<String, Object> source = response.getSource(); log.info("source====================={}", new Gson().toJson(source)); }
4、更新数据
@Test public void updateByMapping() throws Exception{ Map<String, Object> jsonMap = new HashMap<>(); jsonMap.put("orderId", 11111); jsonMap.put("orderName", "修改========1111的订单"); jsonMap.put("content", "修改==============破欸俗人伟大撒打发的"); UpdateRequest request = new UpdateRequest(INDEX,TYPE, jsonMap.get("orderId").toString()).doc(jsonMap); this.update(request); } private boolean update(UpdateRequest request) throws Exception{ UpdateResponse response = restHighLevelClient.update(request); RestStatus restStatus = response.status(); log.info("response====================={}", new Gson().toJson(response)); if (response.status().getStatus() == 200) { return true; } return false; }
5、批量添加
@Test public void batch() throws Exception{ BulkRequest request = new BulkRequest(); request.add(new IndexRequest(INDEX, TYPE, "5678").source( new Gson().toJson(OrderInfo.builder().orderId(5678).orderName("5678的订单").content("我饿请问一日").build()), XContentType.JSON)); request.add(new IndexRequest(INDEX, TYPE, "56781").source( new Gson().toJson(OrderInfo.builder().orderId(56781).orderName("56781的订单").content("我饿请问一日").build()), XContentType.JSON)); request.add(new IndexRequest(INDEX, TYPE, "56782").source( new Gson().toJson(OrderInfo.builder().orderId(56782).orderName("56782的订单").content("我饿请问一日").build()), XContentType.JSON)); request.add(new IndexRequest(INDEX, TYPE, "56783").source( new Gson().toJson(OrderInfo.builder().orderId(56783).orderName("56783的订单").content("我饿请问一日").build()), XContentType.JSON)); BulkResponse response = restHighLevelClient.bulk(request); log.info("response====================={}", new Gson().toJson(response)); }
6、数据查询
@Test public void searchAll() throws Exception{ SearchRequest request = new SearchRequest(INDEX); request.types(TYPE); //SearchRequest request = new SearchRequest(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery()); request.source(searchSourceBuilder); this.search(request); } @Test public void searchPage() throws Exception{ SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.termQuery("orderId", "5678")); //sourceBuilder.from(2); //sourceBuilder.size(5); SearchRequest request = new SearchRequest(INDEX); request.source(sourceBuilder); this.search(request); } @Test public void matchQuery() throws Exception{ /*QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("orderId", "5678") .fuzziness(Fuzziness.AUTO) .prefixLength(3) .maxExpansions(10);*/ SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //searchSourceBuilder.query(matchQueryBuilder); //排序 //searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); searchSourceBuilder.sort(new FieldSortBuilder("orderId").order(SortOrder.ASC)); //过滤字段 String[] includeFields = new String[] {"orderId", "orderName", "content"}; String[] excludeFields = new String[] {"_type"}; searchSourceBuilder.fetchSource(includeFields, excludeFields); //添加高亮 highlightBuilder = new HighlightBuilder(); HighlightBuilder.Field highligthName = new HighlightBuilder.Field("orderName"); //设置高亮字段 highligthName.highlighterType("unified"); highlightBuilder.field(highligthName); HighlightBuilder.Field highligthContent = new HighlightBuilder.Field("content"); //设置高亮字段 highligthName.highlighterType("unified"); highlightBuilder.field(highligthContent); SearchRequest request = new SearchRequest(INDEX); request.types(TYPE); request.source(searchSourceBuilder); this.search(request); } private void search(SearchRequest request) throws Exception{ SearchResponse response = restHighLevelClient.search(request); log.info("response====================={}", new Gson().toJson(response)); //关于请求执行本身的有用信息,如HTTP状态代码、执行时间或请求是否提前终止或超时: RestStatus status = response.status(); TimeValue took = response.getTook(); Boolean terminatedEarly = response.isTerminatedEarly(); boolean timedOut = response.isTimedOut(); log.info("status:{}=======took:{}====terminatedEarly:{}=========timedOut:{}",status,took,terminatedEarly,timedOut); //有关碎片级执行的信息,提供了有关受搜索影响的碎片总数以及成功碎片和不成功碎片的统计信息 int totalShards = response.getTotalShards(); int successfulShards = response.getSuccessfulShards(); int failedShards = response.getFailedShards(); log.info("totalShards:{}=======successfulShards:{}====failedShards:{}",totalShards,successfulShards,failedShards); for (ShardSearchFailure failure : response.getShardFailures()) { log.info("failure==============={}", new Gson().toJson(failure)); } //将返回的数据返回到SearchHits对象中 SearchHits hits = response.getHits(); //SearchHits包含了总点击次数、最大得分等信息: long totalHits = hits.getTotalHits(); float maxScore = hits.getMaxScore(); log.info("totalHits:{}=======maxScore:{}",totalHits,maxScore); //对SearchHits进行遍历得到单个的SearchHit对象,SearchHit包含索引、类型、数据id和数据的得分情况 SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) { String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId(); float score = hit.getScore(); log.info("index:{}=======type:{}=======id:{}=======score:{}",index,type,id,score); //可以将数据JSON字符串或键/值对映射的形式返回。 String sourceAsString = hit.getSourceAsString(); Map<String, Object> sourceAsMap = hit.getSourceAsMap(); String documentTitle = (String) sourceAsMap.get("title"); List<Object> users = (List<Object>) sourceAsMap.get("name"); Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject"); log.info("sourceAsString:{}=======documentTitle:{}=======users:{}",sourceAsString,documentTitle,new Gson().toJson(users)); //设置高亮 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); //获取title高亮显示 HighlightField highlight = highlightFields.get("title"); if(highlight != null){ //获取高亮显示的字段 Text[] fragments = highlight.fragments(); String fragmentString = fragments[0].string(); log.info("fragments:{}=======fragmentString:{}",fragments,fragmentString); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示