• RestTemplate发送HTTPS请求


    RestTemplate发送HTTPS请求

    基础知识:

    Https原理与工作流程及证书校验:https://www.cnblogs.com/zjdxr-up/p/14359904.html

    忽略ssl证书的方式配置:

    import lombok.extern.slf4j.Slf4j;
    
    import org.springframework.http.client.SimpleClientHttpRequestFactory;
    
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    @Slf4j
    public class IgnoreCertificateHttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
        @Override
        protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
            try {
                // 判断类型是http还是https
                if (!(connection instanceof HttpsURLConnection)) {
                    super.prepareConnection(connection, httpMethod);
                    return;
                }
                // 强制转换成HttpsURLConnection
                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
    
                // X509TrustManager用于实现SSL证书的安全校验
                X509TrustManager x509m =
                        new X509TrustManager() {
                            // 返回受信任的X509证书数组。
                            @Override
                            public X509Certificate[] getAcceptedIssuers() {
                                log.info("getAcceptedIssuers");
                                return null;
                            }
    
                            /**
                             * 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。
                             * 在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。
                             */
                            @Override
                            public void checkServerTrusted(X509Certificate[] chain, String authType) {
                                log.info("checkServerTrusted");
                            }
    
                            /**
                             * 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证
                             * 因此我们只需要执行默认的信任管理器的这个方法。Java Secure Socket Extension(JSSE)中,默认的信任管理器类为TrustManager。
                             */
                            @Override
                            public void checkClientTrusted(X509Certificate[] chain, String authType) {
                                log.info("checkClientTrusted");
                            }
                        };
                /**
                 * SSLContext的实例表示安全套接字协议实现,它充当安全套接字工厂或SSLEngine的工厂。
                 * 该类使用一组可选的密钥和信任管理器以及安全随机字节源进行初始化。
                 * 获取一个SSLContext实例对象,并使用我们指定的信任管理器初始化
                 */
                SSLContext sslContext = SSLContext.getInstance("SSL");
    
                /**
                 * 初始化SSL环境
                 * 第二个参数是告诉JSSE使用的可信任证书的来源,设置为null是从javax.net.ssl.trustStore中获得证书
                 * 第三个参数是JSSE生成的随机数,这个参数将影响系统的安全性,设置为null是个好选择,可以保证JSSE的安全性。
                 */
                sslContext.init(null, new TrustManager[] {x509m}, new java.security.SecureRandom());
                // 返回此上下文的 SocketFactory对象。
                SSLSocketFactory socketFactory = sslContext.getSocketFactory();
                httpsConnection.setSSLSocketFactory(socketFactory);
                super.prepareConnection(httpsConnection, httpMethod);
            } catch (NoSuchAlgorithmException exception) {
                throw new RuntimeException(exception);
            } catch (KeyManagementException exception) {
                throw new RuntimeException(exception);
            }
        }
    }
    
    • 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

    使用ssl证书的配置:

    import lombok.extern.slf4j.Slf4j;
    
    import org.springframework.http.client.SimpleClientHttpRequestFactory;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.security.KeyManagementException;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManagerFactory;
    
    @Slf4j
    public class UsingCertificateHttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
        private String type;
        private String path;
        private String password;
    
        public UsingCertificateHttpsClientRequestFactory(String type, String path, String password) {
            super();
            this.type = type;
            this.path = path;
            this.password = password;
        }
    
        @Override
        protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
            // 判断类型是http还是https
            try {
                if (!(connection instanceof HttpsURLConnection)) {
                    super.prepareConnection(connection, httpMethod);
                    return;
                }
                // 强制转换成HttpsURLConnection
                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
                // 加载包含受信任证书的本地密钥库
                // 建议使用:KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                KeyStore keyStore = KeyStore.getInstance(this.type);
                try (FileInputStream inputStream = new FileInputStream(this.path); ) {
                    // 使用 keyStore 类将证书库或信任库文件加载进来
                    keyStore.load(inputStream, this.password.toCharArray());
                    log.info("loading jks ...");
                } catch (CertificateException e) {
                    throw new RuntimeException(e);
                }
                // 使用 KeyManagerFactory 和加载了证书库的 Keystore 实例,产生 KeyManager 实例数组
                // 使用 TrustManagerFactory 和加载了信任库的 Keystore 实例,产生 TrustManager 实例数组
                TrustManagerFactory trustManagerFactory =
                        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                trustManagerFactory.init(keyStore);
                // 使用 SSLContext 初始化 KeyManager 实例数组和 TrustManager 实例数组,从而设定好通信的环境
                SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustManagerFactory.getTrustManagers(), new java.security.SecureRandom());
                // 返回此上下文的 SocketFactory对象。
                SSLSocketFactory socketFactory = sslContext.getSocketFactory();
                // 利用 SSLContext 产生的 SSLSocket 或 SSLServerSocket 进行通信
                httpsConnection.setSSLSocketFactory(socketFactory);
                super.prepareConnection(httpsConnection, httpMethod);
            } catch (KeyStoreException exception) {
                throw new RuntimeException(exception);
            } catch (NoSuchAlgorithmException exception) {
                throw new RuntimeException(exception);
            } catch (KeyManagementException exception) {
                throw new RuntimeException(exception);
            }
        }
    }
    
    • 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

    RestTemplate的配置文件RestTemplateConfiguration:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.StringHttpMessageConverter;
    import org.springframework.web.client.RestTemplate;
    
    import java.nio.charset.StandardCharsets;
    
    @Configuration
    public class RestTemplateConfiguration {
        @Bean("restTemplate")
        public RestTemplate restTemplate() {
            UsingCertificateHttpsClientRequestFactory factory =
                    new UsingCertificateHttpsClientRequestFactory("jks", "D:/truststore.jks", "changeit");
            // 忽略证书方式: IgnoreCertificateHttpsClientRequestFactory factory = new IgnoreCertificateHttpsClientRequestFactory();
            factory.setConnectTimeout(5000);
            factory.setReadTimeout(5000);
            RestTemplate restTemplate = new RestTemplate(factory);
            // 解决中文乱码问题
            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
            return restTemplate;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    机器学习实战-决策树
    【愚公系列】2022年10月 LiteDB数据库-.Net Core中的使用
    基于人工兔优化算法的函数寻优和工程优化
    GBase8s系统表介绍(七)
    论文笔记:ST2Vec: Spatio-Temporal Trajectory SimilarityLearning in Road Networks
    斯特林数
    头歌计算机组成原理汉字字库存储芯片扩展实验
    0822(036天 线程/进程07 Lock接口、集合框架01 Iterator迭代器)
    JavaScript
    即时通讯开发如何撸一个WebSocket服务器
  • 原文地址:https://blog.csdn.net/liwenyang1992/article/details/133040828