激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 使用RestTemplate調(diào)用https接口跳過證書驗證

使用RestTemplate調(diào)用https接口跳過證書驗證

2022-03-06 01:07liangblog Java教程

這篇文章主要介紹了使用RestTemplate調(diào)用https接口跳過證書驗證,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

RestTemplate調(diào)用https接口跳過證書驗證

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; 
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException; 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate; 
public class NoHttpsClientUtils {

  /**
   * 跳過證書效驗的sslcontext
   * 
   * @return
   * @throws Exception
   */
  private static SSLContext createIgnoreVerifySSL() throws Exception {
      SSLContext sc = SSLContext.getInstance("TLS");

      // 實現(xiàn)一個X509TrustManager接口,用于繞過驗證,不用修改里面的方法
      X509TrustManager trustManager = new X509TrustManager() {
          @Override
          public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                  String paramString) throws CertificateException {
          }

          @Override
          public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                  String paramString) throws CertificateException {
          }

          @Override
          public java.security.cert.X509Certificate[] getAcceptedIssuers() {
              return null;
          }
      };
      sc.init(null, new TrustManager[] { trustManager }, null);
      return sc;
  }

  /**
   * 構(gòu)造RestTemplate
   * 
   * @return
   * @throws Exception
   */
  public static RestTemplate getRestTemplate() throws Exception {
      HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
      // 超時
      factory.setConnectionRequestTimeout(5000);
      factory.setConnectTimeout(5000);
      factory.setReadTimeout(5000);
      SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(createIgnoreVerifySSL(),
              // 指定TLS版本
              null,
              // 指定算法
              null,
              // 取消域名驗證
              new HostnameVerifier() {
                  @Override
                  public boolean verify(String string, SSLSession ssls) {
                      return true;
                  }
              });
      CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
      factory.setHttpClient(httpClient);
      RestTemplate restTemplate = new RestTemplate(factory);
      // 解決中文亂碼問題
      restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
      return restTemplate;
  }
}

 

RestTemplate訪問https遇到SSL證書驗證錯誤

今天,遇到了一個SSL證書認(rèn)證的問題,糾結(jié)了好久才解決,學(xué)到了很多東西,記錄下來,分享給大家。

首先說一下大概的背景,我們的項目對接了第三方接口,需要向?qū)Ψ桨l(fā)送https請求。那么問題來了,https請求時需要通過SSL證書認(rèn)證的,今天流程突然走不下去了,看日志發(fā)現(xiàn)是SSL認(rèn)證的問題:

使用RestTemplate調(diào)用https接口跳過證書驗證

在網(wǎng)上找資料,解決問題有兩個思路:

1.通過相關(guān)配置,跳過SSL證書驗證,完成請求。

2.下載證書,將證書導(dǎo)入到JDK的證書管理里面。

第一種方法相當(dāng)于是取巧,逃避問題,我們當(dāng)然不能那么做了,我們要迎接挑戰(zhàn),所以小編直接pass第一條,選擇第二條。

添加Https證書

下載證書

先通過瀏覽器將未簽名驗證的證書保存到本地, 具體步驟:

使用RestTemplate調(diào)用https接口跳過證書驗證

點擊 不安全C> 證書C> 詳細(xì)信息 --> 復(fù)制到文件 然后默認(rèn)選擇 起一個文件名 , 保存即可。

(Mac下載:Mac找不到復(fù)制的按鈕。。。只能另辟蹊徑了)點地址欄上的小鎖,然后點證書,然后將藍(lán)色的文件拖到要下載的文件夾即可。最好給它重命名方便使用。

導(dǎo)入證書

我們需要將證書導(dǎo)入到JDK的證書管理里面才能咋項目中使用我們剛剛下載的證書。導(dǎo)入命令如下:

keytool -import -noprompt -trustcacerts -alias  -keystore
/Users/ZHONGHUI/develop/jdk-12.0.2.jdk/Contents/Home/lib/security/cacerts 
-storepass changeit -file eleme.cer

其中,因為我們用的是JDK12,跟常用的JDK8目錄是不一樣的,所以我的cacerts目錄是:/Users/ZHONGHUI/develop/jdk-12.0.2.jdk/Contents/Home/lib/security/cacerts,如果你用的是JDK1.8或者1.7的話,那么你的cacerts在jre下的 /lib/security/下。eleme是我們給復(fù)制過來的證書取得別名,eleme.cer就是我們下載改名后的證書。changeit 是密碼,如果changeit不行的話,就試試changeme,一般是changeit。

生成keystore文件

keytool -import -storepass changeit -file eleme.cer -keystore eleme.keystore

然后就會生成一個eleme.keystore文件,若權(quán)限不夠,加sudo即可。將它復(fù)制到項目的類路徑下。

項目中配置

將下面的RestTemplateConfig替換原來的:

package com..xxx.config; 
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.client.RestTemplate; 
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

@Configuration
public class RestTemplateConfig { 
  @Autowired
  private FastJsonHttpMessageConverter httpMessageConverter;

  @Bean
  RestTemplate restTemplate() throws Exception {
  	HttpComponentsClientHttpRequestFactory factory = new                                                    
  	        HttpComponentsClientHttpRequestFactory();
  	    factory.setConnectionRequestTimeout(5 * 60 * 1000);
  	    factory.setConnectTimeout(5 * 60 * 1000);
  	    factory.setReadTimeout(5 * 60 * 1000);
  	    // https
  	    SSLContextBuilder builder = new SSLContextBuilder();
  	    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
  	    ClassPathResource resource = new ClassPathResource("nonghang.keystore");
  	    InputStream inputStream = resource.getInputStream();
  	    keyStore.load(inputStream, null);
  	    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
  	    Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
  	            .register("http", new PlainConnectionSocketFactory())
  	            .register("https", socketFactory).build();
  	    PoolingHttpClientConnectionManager phccm = new PoolingHttpClientConnectionManager(registry);
  	    phccm.setMaxTotal(200);
  	    CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).setConnectionManager(phccm).setConnectionManagerShared(true).build();
  	    factory.setHttpClient(httpClient);
  	    RestTemplate restTemplate = new RestTemplate(factory);
  	    List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
          ArrayList<HttpMessageConverter<?>> convertersValid = new ArrayList<>();
          for (HttpMessageConverter<?> converter : converters) {
              if (converter instanceof MappingJackson2HttpMessageConverter ||
                  converter instanceof MappingJackson2XmlHttpMessageConverter) {
                  continue;
              }
              convertersValid.add(converter);
          }
          convertersValid.add(httpMessageConverter);
          restTemplate.setMessageConverters(convertersValid);
  	    inputStream.close();
      return restTemplate;
  }
}

好啦,萬事俱備只欠東風(fēng),自信滿滿的試了一下,發(fā)現(xiàn)還是行不通,深受打擊的我決定還是去看看導(dǎo)致這類報錯的原因。

從根源出發(fā),https的socket工作原理是怎樣的?

https的socket工作原理流程圖如下:

使用RestTemplate調(diào)用https接口跳過證書驗證

那么,什么是SSL證書?

SSL 證書就是遵守 SSL協(xié)議,由受信任的數(shù)字證書頒發(fā)機構(gòu)CA,在驗證服務(wù)器身份后頒發(fā),具有服務(wù)器身份驗證和數(shù)據(jù)傳輸加密功能。

首先,要知道導(dǎo)致報這個異常的原因不僅僅是因為證書校驗不通過。

1.在我們通過https鏈接服務(wù)器時,服務(wù)器會給我們返回一個證書,這個證書可能經(jīng)過CA認(rèn)證,也可能是未認(rèn)證的自制證書,客戶端拿到這個證書后會對這個證書進行驗證,如果是經(jīng)過CA驗證的證書,自然證書校驗就能通過,自制證書自然就校驗不同過,從而導(dǎo)致上邊的異常。

2.證書校驗通過后,還需要校驗訪問的域名是否和證書指定的域名是否匹配。未匹配也會導(dǎo)致如上異常。

3.上邊兩步都校驗通過了才開始進行握手,但握手也有可能失敗,從而導(dǎo)致上邊的異常。

以上三個步驟中任何一個出了問題,都會連接失敗。

首先,我們獲取的證書是經(jīng)過CA認(rèn)證的,理應(yīng)不會出現(xiàn)不通過的情況,第三方的域名也是沒有問題的。那么到底是哪里出了問題呢?

后來我們從網(wǎng)絡(luò)組那邊了解到,他們那邊對最近做了大的改動,之前的proxy都要重新加,加的時候把我們的給漏掉了。。。。辛苦大半天,被坑慘了啊。。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/weixin_42551921/article/details/118718678

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人福利视频 | 久久久成人免费视频 | 欧美成人小视频 | 国产亚洲高清视频 | 久久亚洲线观看视频 | 免费国产一级特黄久久 | 色吧综合网 | 亚洲精品tv久久久久久久久久 | 午色影院| 国产九色在线播放九色 | 法国性经典xxxhd | 99国语露脸久久精品国产ktv | 高清一区二区在线观看 | 久久精品中文字幕一区 | 九色在线78m | 在线 日本 制服 中文 欧美 | 亚洲影视在线 | 欧美大穴 | 毛片韩国 | 国产精品www | 欧美成人国产va精品日本一级 | 国产亚洲网| 黄色av免费网站 | 黄色大片免费网站 | 日韩.www| 91成人天堂久久成人 | 91热久久免费频精品黑人99 | 黄色男女视频 | 亚洲精中文字幕二区三区 | 中文字幕在线播放视频 | 操操操日日日干干干 | 国产精品视频 | 在线a毛片免费视频观看 | 久久久www免费看片 亚洲综合视频一区 | 亚洲午夜久久久精品一区二区三区 | 日本一区二区不卡在线观看 | 钻石午夜影院 | 久久久国产视频 | 91精品国产777在线观看 | 欧美日韩中文字幕在线 | 亚洲爱爱网站 |