云搜索服务 CSS-通过Spring Boot接入集群:使用Spring Boot接入HTTPS集群(使用安全证书)

时间:2024-08-14 09:17:26

使用Spring Boot接入HTTPS集群(使用安全证书)

该场景适用于使用安全证书连接安全模式+HTTPS协议的集群。

  1. 获取安全证书(CloudSearchService.cer)。
    1. 登录 云搜索服务 控制台。
    2. 选择“集群管理”进入集群列表。
    3. 单击对应集群的名称,进入集群基本信息页面。
    4. “基本信息”页面,单击“HTTPS访问”后面的“下载证书”
      图1 下载证书
  2. 转换安全证书(CloudSearchService.cer)。将下载的安全证书上传到客户端机器上,使用keytool工具将“.cer”证书转换成Java可以读取的“.jks”证书格式。
    • 在Linux系统中,执行如下命令转换证书。
      keytool -import -alias newname -keystore ./truststore.jks -file ./CloudSearchService.cer 
    • 在Windows系统中,执行如下命令转换证书。
      keytool -import -alias newname -keystore .\truststore.jks -file .\CloudSearchService.cer

    其中,newname是由用户自定义的证书名称。

    该命令执行后,会提示设置证书密码,并确认密码。请保存该密码,后续接入集群会使用。

  3. application.properties配置文件:
    1
    2
    3
    elasticsearch.url=host1:9200,host2:9200
    elasticsearch.username=username
    elasticsearch.password=password
    
    表3 参数说明

    参数

    描述

    host

    Elasticsearch集群节点的IP地址。

    username

    访问集群的用户名。

    password

    用户名对应的密码。

  4. 配置代码:
    • com.xxx为项目目录,例如com.company.project。
    • com.xxx.repository为仓库目录,通过extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository进行具体定义。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    package com.xxx.configuration;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    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.config.AbstractElasticsearchConfiguration;
    import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    @Configuration
    @EnableElasticsearchRepositories(basePackages = "com.xxx.repository")
    @ComponentScan(basePackages = "com.xxx")
    public class Config extends AbstractElasticsearchConfiguration {
        @Value("${elasticsearch.url}")
        public String elasticsearchUrl;
        @Value("${elasticsearch.username}")
        public String elasticsearchUsername;
        @Value("${elasticsearch.password}")
        public String elasticsearchPassword;
        @Override
        @Bean
        public RestHighLevelClient elasticsearchClient() {
            SSLContext sc = null;
            try {
                TrustManager[] tm = {new MyX509TrustManager(cerFilePath, cerPassword)};
                sc = SSLContext.getInstance("SSL", "SunJSSE");
                sc.init(null, tm, new SecureRandom());
            } catch (Exception e) {
                e.printStackTrace();
            }
            final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(StringHostParse(elasticsearchUrl))
                .usingSsl(sc, new NullHostNameVerifier())
                .withBasicAuth(elasticsearchUsername, elasticsearchPassword)
                .build();
            return RestClients.create(clientConfiguration).rest();
        }
    
        private String[] StringHostParse(String hostAndPorts) {
            return hostAndPorts.split(",");
        }
    
        public static class MyX509TrustManager implements X509TrustManager {
            X509TrustManager sunJSSEX509TrustManager;
            MyX509TrustManager(String cerFilePath, String cerPassword) throws Exception {
                File file = new File(cerFilePath);
                if (!file.isFile()) {
                    throw new Exception("Wrong Certification Path");
                }
                System.out.println("Loading KeyStore " + file + "...");
                InputStream in = new FileInputStream(file);
                KeyStore ks = KeyStore.getInstance("JKS");
                ks.load(in, cerPassword.toCharArray());
                TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
                tmf.init(ks);
                TrustManager[] tms = tmf.getTrustManagers();
                for (TrustManager tm : tms) {
                    if (tm instanceof X509TrustManager) {
                        sunJSSEX509TrustManager = (X509TrustManager) tm;
                        return;
                    }
                }
                throw new Exception("Couldn't initialize");
            }
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }
        public static class NullHostNameVerifier implements HostnameVerifier {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        }
    }
    

    其中,cerFilePathcerPassword是生成的.jks证书的存放路径及其密码。

support.huaweicloud.com/bestpractice-css/css_07_0034.html