ToB企服应用市场:ToB评测及商务社交产业平台

标题: java与es8实战之五:SpringBoot应用中操作es8(带安全检查:https、账号密码 [打印本页]

作者: 郭卫东    时间: 2023-9-2 16:27
标题: java与es8实战之五:SpringBoot应用中操作es8(带安全检查:https、账号密码
欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览




部署elasticsearch集群(需要安全检查)

创建API Key

  1. curl -X POST "https://localhost:9200/_security/api_key?pretty" \
  2. --cacert es01.crt \
  3. -u elastic:123456 \
  4. -H 'Content-Type: application/json' \
  5. -d'
  6. {
  7.   "name": "my-api-key-10d",
  8.   "expiration": "10d"
  9. }
  10. '
复制代码
  1. {
  2.   "id" : "eUV1V4EBucGIxpberGuJ",
  3.   "name" : "my-api-key-10d",
  4.   "expiration" : 1655893738633,
  5.   "api_key" : "YyhSTh9ETz2LKBk3-Iy2ew",
  6.   "encoded" : "ZVVWMVY0RUJ1Y0dJeHBiZXJHdUo6WXloU1RoOUVUejJMS0JrMy1JeTJldw=="
  7. }
复制代码
Java应用连接elasticsearch的核心套路


新建子工程

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.    
  5.     <parent>
  6.         <artifactId>elasticsearch-tutorials</artifactId>
  7.         <groupId>com.bolingcavalry</groupId>
  8.         <version>1.0-SNAPSHOT</version>
  9.         <relativePath>../pom.xml</relativePath>
  10.     </parent>
  11.     <modelVersion>4.0.0</modelVersion>
  12.     <groupId>com.bolingcavalry</groupId>
  13.    
  14.     <artifactId>crud-with-security</artifactId>
  15.     <packaging>jar</packaging>
  16.    
  17.     <name>crud-with-security</name>
  18.     <version>1.0-SNAPSHOT</version>
  19.     <url>https://github.com/zq2599</url>
  20.    
  21.     <dependencyManagement>
  22.         <dependencies>
  23.             <dependency>
  24.                 <groupId>org.springframework.boot</groupId>
  25.                 <artifactId>spring-boot-dependencies</artifactId>
  26.                 <version>${springboot.version}</version>
  27.                 <type>pom</type>
  28.                 <scope>import</scope>
  29.             </dependency>
  30.         </dependencies>
  31.     </dependencyManagement>
  32.     <dependencies>
  33.         <dependency>
  34.             <groupId>org.springframework.boot</groupId>
  35.             <artifactId>spring-boot-starter-actuator</artifactId>
  36.         </dependency>
  37.         
  38.         <dependency>
  39.             <groupId>org.springframework.boot</groupId>
  40.             <artifactId>spring-boot-configuration-processor</artifactId>
  41.             <optional>true</optional>
  42.         </dependency>
  43.         <dependency>
  44.             <groupId>org.projectlombok</groupId>
  45.             <artifactId>lombok</artifactId>
  46.         </dependency>
  47.         <dependency>
  48.             <groupId>org.springframework.boot</groupId>
  49.             <artifactId>spring-boot-starter-web</artifactId>
  50.         </dependency>
  51.         <dependency>
  52.             <groupId>org.springframework.boot</groupId>
  53.             <artifactId>spring-boot-starter-test</artifactId>
  54.             <scope>test</scope>
  55.             
  56.             <exclusions>
  57.                 <exclusion>
  58.                     <groupId>junit</groupId>
  59.                     <artifactId>junit</artifactId>
  60.                 </exclusion>
  61.             </exclusions>
  62.         </dependency>
  63.         
  64.         <dependency>
  65.             <groupId>org.junit.jupiter</groupId>
  66.             <artifactId>junit-jupiter-api</artifactId>
  67.             <scope>test</scope>
  68.         </dependency>
  69.         <dependency>
  70.             <groupId>org.junit.jupiter</groupId>
  71.             <artifactId>junit-jupiter-engine</artifactId>
  72.             <scope>test</scope>
  73.         </dependency>
  74.         
  75.         <dependency>
  76.             <groupId>co.elastic.clients</groupId>
  77.             <artifactId>elasticsearch-java</artifactId>
  78.         </dependency>
  79.         <dependency>
  80.             <groupId>com.fasterxml.jackson.core</groupId>
  81.             <artifactId>jackson-databind</artifactId>
  82.         </dependency>
  83.         
  84.         <dependency>
  85.             <groupId>jakarta.json</groupId>
  86.             <artifactId>jakarta.json-api</artifactId>
  87.         </dependency>
  88.         <dependency>
  89.             <groupId>org.springframework.boot</groupId>
  90.             <artifactId>spring-boot-starter-web</artifactId>
  91.         </dependency>
  92.     </dependencies>
  93.     <build>
  94.         <plugins>
  95.             
  96.             <plugin>
  97.                 <groupId>org.apache.maven.plugins</groupId>
  98.                 <artifactId>maven-surefire-plugin</artifactId>
  99.                 <version>3.0.0-M4</version>
  100.                 <configuration>
  101.                     <skipTests>false</skipTests>
  102.                 </configuration>
  103.             </plugin>
  104.             <plugin>
  105.                 <groupId>org.springframework.boot</groupId>
  106.                 <artifactId>spring-boot-maven-plugin</artifactId>
  107.                 <configuration>
  108.                     <excludes>
  109.                         <exclude>
  110.                             <groupId>org.projectlombok</groupId>
  111.                             <artifactId>lombok</artifactId>
  112.                         </exclude>
  113.                     </excludes>
  114.                 </configuration>
  115.             </plugin>
  116.         </plugins>
  117.         <resources>
  118.             <resource>
  119.                 <directory>src/main/resources</directory>
  120.                 <includes>
  121.                     <include>**/*.*</include>
  122.                 </includes>
  123.             </resource>
  124.         </resources>
  125.     </build>
  126. </project>
复制代码
配置文件

  1. elasticsearch:
  2.   username: elastic
  3.   passwd: 123456
  4.   apikey: ZVVWMVY0RUJ1Y0dJeHBiZXJHdUo6WXloU1RoOUVUejJMS0JrMy1JeTJldw==
  5.   # 多个IP逗号隔开
  6.   hosts: 127.0.0.1:9200
复制代码
编码:启动类

  1. @SpringBootApplication
  2. public class SecurityApplication {
  3.     public static void main(String[] args) {
  4.         SpringApplication.run(SecurityApplication.class, args);
  5.     }
  6. }
复制代码
编码:配置文件


  1. package com.bolingcavalry.security.config;
  2. import co.elastic.clients.elasticsearch.ElasticsearchClient;
  3. import co.elastic.clients.json.jackson.JacksonJsonpMapper;
  4. import co.elastic.clients.transport.ElasticsearchTransport;
  5. import co.elastic.clients.transport.rest_client.RestClientTransport;
  6. import lombok.Setter;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.apache.http.Header;
  9. import org.apache.http.HttpHost;
  10. import org.apache.http.auth.AuthScope;
  11. import org.apache.http.auth.UsernamePasswordCredentials;
  12. import org.apache.http.client.CredentialsProvider;
  13. import org.apache.http.conn.ssl.NoopHostnameVerifier;
  14. import org.apache.http.impl.client.BasicCredentialsProvider;
  15. import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
  16. import org.apache.http.message.BasicHeader;
  17. import org.apache.http.ssl.SSLContextBuilder;
  18. import org.apache.http.ssl.SSLContexts;
  19. import org.elasticsearch.client.RestClient;
  20. import org.elasticsearch.client.RestClientBuilder;
  21. import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
  22. import org.springframework.boot.context.properties.ConfigurationProperties;
  23. import org.springframework.context.annotation.Bean;
  24. import org.springframework.context.annotation.Configuration;
  25. import org.springframework.core.io.ClassPathResource;
  26. import org.springframework.util.StringUtils;
  27. import javax.net.ssl.SSLContext;
  28. import java.io.IOException;
  29. import java.io.InputStream;
  30. import java.nio.file.Files;
  31. import java.nio.file.Path;
  32. import java.nio.file.Paths;
  33. import java.security.KeyManagementException;
  34. import java.security.KeyStore;
  35. import java.security.KeyStoreException;
  36. import java.security.NoSuchAlgorithmException;
  37. import java.security.cert.Certificate;
  38. import java.security.cert.CertificateException;
  39. import java.security.cert.CertificateFactory;
  40. @ConfigurationProperties(prefix = "elasticsearch") //配置的前缀
  41. @Configuration
  42. @Slf4j
  43. public class ClientConfig {
  44.     @Setter
  45.     private String hosts;
  46.     @Setter
  47.     private String username;
  48.     @Setter
  49.     private String passwd;
  50.     @Setter
  51.     private String apikey;
  52.     /**
  53.      * 解析配置的字符串,转为HttpHost对象数组
  54.      * @return
  55.      */
  56.     private HttpHost[] toHttpHost() {
  57.         if (!StringUtils.hasLength(hosts)) {
  58.             throw new RuntimeException("invalid elasticsearch configuration");
  59.         }
  60.         String[] hostArray = hosts.split(",");
  61.         HttpHost[] httpHosts = new HttpHost[hostArray.length];
  62.         HttpHost httpHost;
  63.         for (int i = 0; i < hostArray.length; i++) {
  64.             String[] strings = hostArray[i].split(":");
  65.             httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "https");
  66.             httpHosts[i] = httpHost;
  67.         }
  68.         return httpHosts;
  69.     }
  70.     @Bean
  71.     public ElasticsearchClient clientByPasswd() throws Exception {
  72.         ElasticsearchTransport transport = getElasticsearchTransport(username, passwd, toHttpHost());
  73.         return new ElasticsearchClient(transport);
  74.     }
  75.     private static SSLContext buildSSLContext() {
  76.         ClassPathResource resource = new ClassPathResource("es01.crt");
  77.         SSLContext sslContext = null;
  78.         try {
  79.             CertificateFactory factory = CertificateFactory.getInstance("X.509");
  80.             Certificate trustedCa;
  81.             try (InputStream is = resource.getInputStream()) {
  82.                 trustedCa = factory.generateCertificate(is);
  83.             }
  84.             KeyStore trustStore = KeyStore.getInstance("pkcs12");
  85.             trustStore.load(null, null);
  86.             trustStore.setCertificateEntry("ca", trustedCa);
  87.             SSLContextBuilder sslContextBuilder = SSLContexts.custom()
  88.                     .loadTrustMaterial(trustStore, null);
  89.             sslContext = sslContextBuilder.build();
  90.         } catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException |
  91.                  KeyManagementException e) {
  92.             log.error("ES连接认证失败", e);
  93.         }
  94.         return sslContext;
  95.     }
  96.     private static ElasticsearchTransport getElasticsearchTransport(String username, String passwd, HttpHost...hosts) {
  97.         // 账号密码的配置
  98.         final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
  99.         credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, passwd));
  100.         // 自签证书的设置,并且还包含了账号密码
  101.         HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
  102.                 .setSSLContext(buildSSLContext())
  103.                 .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
  104.                 .setDefaultCredentialsProvider(credentialsProvider);
  105.         // 用builder创建RestClient对象
  106.         RestClient client = RestClient
  107.                            .builder(hosts)
  108.                            .setHttpClientConfigCallback(callback)
  109.                            .build();
  110.         return new RestClientTransport(client, new JacksonJsonpMapper());
  111.     }
  112.     private static ElasticsearchTransport getElasticsearchTransport(String apiKey, HttpHost...hosts) {
  113.         // 将ApiKey放入header中
  114.         Header[] headers = new Header[] {new BasicHeader("Authorization", "ApiKey " + apiKey)};
  115.         // es自签证书的设置
  116.         HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
  117.                 .setSSLContext(buildSSLContext())
  118.                 .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
  119.         // 用builder创建RestClient对象
  120.         RestClient client = RestClient
  121.                            .builder(hosts)
  122.                            .setHttpClientConfigCallback(callback)
  123.                            .setDefaultHeaders(headers)
  124.                            .build();
  125.         return new RestClientTransport(client, new JacksonJsonpMapper());
  126.     }
  127.     @Bean
  128.     public ElasticsearchClient clientByApiKey() throws Exception {
  129.         ElasticsearchTransport transport = getElasticsearchTransport(apikey, toHttpHost());
  130.         return new ElasticsearchClient(transport);
  131.     }
  132. }
复制代码
编码:业务类

  1. package com.bolingcavalry.security.service;
  2. import co.elastic.clients.elasticsearch.ElasticsearchClient;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import javax.annotation.Resource;
  6. import java.io.IOException;
  7. @Service
  8. public class ESService {
  9.     @Resource(name="clientByPasswd")
  10.     private ElasticsearchClient elasticsearchClient;
  11.     public void addIndex(String name) throws IOException {
  12.         elasticsearchClient.indices().create(c -> c.index(name));
  13.     }
  14.     public boolean indexExists(String name) throws IOException {
  15.         return elasticsearchClient.indices().exists(b -> b.index(name)).value();
  16.     }
  17.     public void delIndex(String name) throws IOException {
  18.         elasticsearchClient.indices().delete(c -> c.index(name));
  19.     }
  20. }
复制代码
编码:单元测试

  1. package com.bolingcavalry.security.service;
  2. import org.junit.jupiter.api.Assertions;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. @SpringBootTest
  7. class ESServiceTest {
  8.     @Autowired
  9.     ESService esService;
  10.     @Test
  11.     void addIndex() throws Exception {
  12.         String indexName = "test_index";
  13.         Assertions.assertFalse(esService.indexExists(indexName));
  14.         esService.addIndex(indexName);
  15.         Assertions.assertTrue(esService.indexExists(indexName));
  16.         esService.delIndex(indexName);
  17.         Assertions.assertFalse(esService.indexExists(indexName));
  18.     }
  19. }
复制代码
验证:账号密码鉴权

验证:ApiKey鉴权

源码下载

名称链接备注项目主页https://github.com/zq2599/blog_demos该项目在GitHub上的主页git仓库地址(https)https://github.com/zq2599/blog_demos.git该项目源码的仓库地址,https协议git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议
欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4