首先根据如下操作生成证书,配置springboot https,生成一个简单的https web服务

https://www.cnblogs.com/qq931399960/p/11889349.html

验证客户端pom依赖

  1. </dependency>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.httpcomponents</groupId>
  8. <artifactId>httpclient</artifactId>
  9. <version>4.5.10</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.httpcomponents</groupId>
  13. <artifactId>httpcore</artifactId>
  14. <version>4.4.12</version>
  15. </dependency>

httpclient和httpcore版本要对应,否则可能会出现异常

验证方式包括跳过证书验证,也即是添加信任,就像浏览器访问自签名https服务时,页面会给出提示“您的链接不是私密连接”,点击了高级,继续前往即是对该服务添加了信任,可以继续访问该网站服务,另外一种方式就是通过服务器证书来验证,下面就直接上代码

跳过证书验证方式

  1. package com.demo.bootdemo;
  2.  
  3. import java.security.cert.CertificateException;
  4. import java.security.cert.X509Certificate;
  5.  
  6. import javax.net.ssl.HostnameVerifier;
  7. import javax.net.ssl.HttpsURLConnection;
  8. import javax.net.ssl.SSLContext;
  9. import javax.net.ssl.SSLSession;
  10. import javax.net.ssl.TrustManager;
  11. import javax.net.ssl.X509TrustManager;
  12.  
  13. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  14. import org.apache.http.impl.client.HttpClients;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import org.springframework.context.annotation.Bean;
  18. import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
  19. import org.springframework.stereotype.Component;
  20. import org.springframework.web.client.RestTemplate;
  21.  
  22. @Component
  23. public class SkipVerifyRestTemplateBuilder {
  24.  
  25. private Logger logger = LoggerFactory.getLogger(SkipVerifyRestTemplateBuilder.class);
  26.  
  27. // 初始化ssl resttemplate
  28. @Bean("skipVerifyRestTemplate")
  29. public RestTemplate skipVerifyRestTemplate() {
  30. RestTemplate rest = new RestTemplate();
  31.  
  32. SSLConnectionSocketFactory buildSSLSocketFactory = null;
  33. try {
  34. buildSSLSocketFactory = this.buildSSLSocketFactory();
  35. } catch (Exception e) {
  36. logger.error("", e);
  37. }
  38.  
  39. HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
  40. HttpClients.custom().setSSLSocketFactory(buildSSLSocketFactory).build());
  41.  
  42. factory.setConnectionRequestTimeout(1000);
  43. factory.setConnectTimeout(1000);
  44.  
  45. rest.setRequestFactory(factory);
  46. return rest;
  47. }
  48.  
  49. private SSLConnectionSocketFactory buildSSLSocketFactory() throws Exception {
  50. SSLContext sslContext = SSLContext.getInstance("SSL");
  51. // 设置信任证书(绕过TrustStore验证)
  52. sslContext.init(null, new TrustManager[] { new AuthX509TrustManager() }, null);
  53. HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
  54.  
  55. SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
  56. new String[] { "TLSv1" }, null, new HostnameVerifier() {
  57. // hostname,默认返回true,不验证hostname
  58. @Override
  59. public boolean verify(String urlHostName, SSLSession session) {
  60. return true;
  61. }
  62. });
  63. return sslConnectionSocketFactory;
  64. }
  65.  
  66. private class AuthX509TrustManager implements TrustManager, X509TrustManager {
  67. public X509Certificate[] getAcceptedIssuers() {
  68. return null;
  69. }
  70.  
  71. public void checkServerTrusted(X509Certificate[] certs, String authType)
  72. throws java.security.cert.CertificateException {
  73. return;
  74. }
  75.  
  76. public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
  77. return;
  78. }
  79. }
  80. }

第二种跳过证书验证方式

  1. package com.demo.bootdemo;
  2.  
  3. import java.io.IOException;
  4. import java.security.KeyStore;
  5. import java.security.cert.CertificateException;
  6. import java.security.cert.X509Certificate;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9.  
  10. import javax.net.ssl.HostnameVerifier;
  11. import javax.net.ssl.HttpsURLConnection;
  12. import javax.net.ssl.SSLContext;
  13. import javax.net.ssl.SSLSession;
  14.  
  15. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  16. import org.apache.http.conn.ssl.TrustStrategy;
  17. import org.apache.http.impl.client.HttpClients;
  18. import org.apache.http.ssl.SSLContexts;
  19. import org.springframework.context.annotation.Bean;
  20. import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
  21. import org.springframework.stereotype.Component;
  22. import org.springframework.web.client.RestTemplate;
  23.  
  24. @Component
  25. public class SecondSkipVerifyRestTemplateBuilder {
  26.  
  27. @Bean("secondSkipRestTemplate")
  28. public RestTemplate verifyCaRestTemplate() {
  29. RestTemplate rest = new RestTemplate();
  30. SSLConnectionSocketFactory ssLSocketFactory = null;
  31. try {
  32. ssLSocketFactory = sslFactory("PKCS12", "abc123");
  33. } catch (Exception e) {
  34. // TODO Auto-generated catch block
  35. e.printStackTrace();
  36. }
  37.  
  38. HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(
  39. HttpClients.custom().setSSLSocketFactory(ssLSocketFactory).build());
  40. // 设置传递数据超时时长
  41. httpRequestFactory.setReadTimeout(1000);
  42.  
  43. rest.setRequestFactory(httpRequestFactory);
  44.  
  45. // 如果返回的数据非json则可能需要添加对应httpmessageconverter
  46. // Jaxb2RootElementHttpMessageConverter converter = new
  47. // Jaxb2RootElementHttpMessageConverter();
  48. //
  49. // List<MediaType> mediaTypeList = new ArrayList<>();
  50. // mediaTypeList.addAll(converter.getSupportedMediaTypes());
  51. // mediaTypeList.add(MediaType.TEXT_HTML);
  52. // converter.setSupportedMediaTypes(mediaTypeList);
  53. //
  54. // List<HttpMessageConverter<?>> list = new ArrayList<>();
  55. // list.add(converter);
  56. // rest.setMessageConverters(list);
  57.  
  58. return rest;
  59.  
  60. }
  61.  
  62. public SSLConnectionSocketFactory sslFactory(String keyStoreType, String keyPassword) {
  63. SSLConnectionSocketFactory sslConnectionSocketFactory = null;
  64. try {
  65. SSLContext sslcontext = SSLContexts.custom()
  66. // //忽略掉对服务器端证书的校验
  67. .loadTrustMaterial(new TrustStrategy() {
  68. @Override
  69. public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  70. return true;
  71. }
  72. }).build();
  73. sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
  74. SSLConnectionSocketFactory.getDefaultHostnameVerifier());
  75. } catch (Exception e) {
  76. e.printStackTrace();
  77. }
  78. return sslConnectionSocketFactory;
  79. }
  80.  
  81. }

根据证书验证

  1. package com.demo.bootdemo;
  2.  
  3. import java.io.IOException;
  4. import java.security.KeyStore;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7.  
  8. import javax.net.ssl.HostnameVerifier;
  9. import javax.net.ssl.SSLContext;
  10. import javax.net.ssl.SSLSession;
  11.  
  12. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  13. import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
  14. import org.apache.http.impl.client.HttpClients;
  15. import org.apache.http.ssl.SSLContexts;
  16. import org.slf4j.Logger;
  17. import org.slf4j.LoggerFactory;
  18. import org.springframework.beans.factory.annotation.Value;
  19. import org.springframework.context.annotation.Bean;
  20. import org.springframework.core.io.Resource;
  21. import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
  22. import org.springframework.stereotype.Component;
  23. import org.springframework.web.client.RestTemplate;
  24.  
  25. @Component
  26. public class VerifyCaRestTemplateBuilder {
  27.  
  28. private Logger logger = LoggerFactory.getLogger(VerifyCaRestTemplateBuilder.class);
  29.  
  30. @Value("classpath:cert.p12")
  31. private Resource certFile;
  32.  
  33. @Bean("verifyCaRestTemplate")
  34. public RestTemplate verifyCaRestTemplate() {
  35. RestTemplate rest = new RestTemplate();
  36.  
  37. SSLConnectionSocketFactory ssLSocketFactory = null;
  38. try {
  39. ssLSocketFactory = sslFactory("PKCS12", "abc123");
  40. } catch (Exception e) {
  41. logger.error("", e);
  42. }
  43.  
  44. HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(
  45. HttpClients.custom().setSSLSocketFactory(ssLSocketFactory).build());
  46. // 设置传递数据超时时长
  47. httpRequestFactory.setReadTimeout(1000);
  48.  
  49. rest.setRequestFactory(httpRequestFactory);
  50.  
  51. // 如果返回的数据非json则可能需要添加对应httpmessageconverter
  52. // Jaxb2RootElementHttpMessageConverter converter = new
  53. // Jaxb2RootElementHttpMessageConverter();
  54. //
  55. // List<MediaType> mediaTypeList = new ArrayList<>();
  56. // mediaTypeList.addAll(converter.getSupportedMediaTypes());
  57. // mediaTypeList.add(MediaType.TEXT_HTML);
  58. // converter.setSupportedMediaTypes(mediaTypeList);
  59. //
  60. // List<HttpMessageConverter<?>> list = new ArrayList<>();
  61. // list.add(converter);
  62. // rest.setMessageConverters(list);
  63.  
  64. return rest;
  65.  
  66. }
  67.  
  68. public SSLConnectionSocketFactory sslFactory(String keyStoreType, String keyPassword) {
  69. SSLConnectionSocketFactory sslConnectionSocketFactory = null;
  70. try {
  71. KeyStore keyStore = null;
  72. try {
  73. keyStore = KeyStore.getInstance(keyStoreType);
  74. keyStore.load(certFile.getInputStream(), keyPassword.toCharArray());
  75. } catch (IOException e) {
  76. logger.error("", e);
  77. }
  78.  
  79. HostnameVerifier hv = new HostnameVerifier() {
  80. @Override
  81. public boolean verify(String urlHostName, SSLSession session) {
  82. // 如果需要验证https域名,可以在该处做判断,如果访问的hostname与判断不一致,则会出现如下异常
  83. // if("localhost".equals(urlHostName)) {
  84. // return true;
  85. // }else {
  86. // return false;
  87. // }
  88. // 此处不校验hostname,接收所有hostname,只是用于测试。
  89. return true;
  90. }
  91. };
  92.  
  93. SSLContext sslcontext = SSLContexts.custom()
  94. .loadTrustMaterial(certFile.getFile(), keyPassword.toCharArray(), new TrustSelfSignedStrategy())
  95. .loadKeyMaterial(keyStore, keyPassword.toCharArray()).build();
  96. sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, hv);
  97.  
  98. } catch (Exception e) {
  99. e.printStackTrace();
  100. }
  101. return sslConnectionSocketFactory;
  102. }
  103.  
  104. }

注:在上述HostnameVerifier 中,可以验证hostname有效性,如果无效,返回fase,则会出现类似以下异常

javax.net.ssl.SSLPeerUnverifiedException: Certificate for <localhost> doesn't match any of the subject alternative names: []

测试controller

  1. package com.demo.bootdemo;
  2.  
  3. import javax.annotation.Resource;
  4.  
  5. import org.springframework.http.ResponseEntity;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import org.springframework.web.client.RestTemplate;
  10.  
  11. @Controller
  12. public class HttpsSendController {
  13.  
  14. @Resource(name = "skipVerifyRestTemplate")
  15. private RestTemplate skipVerifyRestTemplate;
  16.  
  17. @Resource(name = "verifyCaRestTemplate")
  18. private RestTemplate verifyCaRestTemplate;
  19.  
  20. @Resource(name = "secondSkipRestTemplate")
  21. private RestTemplate secondSkipRestTemplate;
  22.  
  23. @RequestMapping("/skip")
  24. @ResponseBody
  25. public String skipVerifyCert() {
  26. ResponseEntity<String> forEntity = skipVerifyRestTemplate.getForEntity("https://127.0.0.1:8443/test",
  27. String.class, new Object[] {});
  28. return forEntity.getBody();
  29. }
  30.  
  31. @RequestMapping("/secondskip")
  32. @ResponseBody
  33. public String secondSkipVerifyCert() {
  34. ResponseEntity<String> forEntity = skipVerifyRestTemplate.getForEntity("https://127.0.0.1:8443/test",
  35. String.class, new Object[] {});
  36. return forEntity.getBody();
  37. }
  38.  
  39. @RequestMapping("/verify")
  40. @ResponseBody
  41. public String verifyCert() {
  42. ResponseEntity<String> forEntity = verifyCaRestTemplate.getForEntity("https://127.0.0.1:8443/test",
  43. String.class, new Object[] {});
  44. return forEntity.getBody();
  45. }
  46.  
  47. }

可分别访问当前客户端的skip、secondskip、verify验证结果

java客户端验证https连接(忽略证书验证和证书验证两种方式)的更多相关文章

  1. Java通过图片url地址获取图片base64位字符串的两种方式

    工作中遇到通过图片的url获取图片base64位的需求.一开始是用网上的方法,通过工具类Toolkit,虽然实现的代码比较简短,不过偶尔会遇到图片转成base64位不正确的情况,至今不知道为啥. 之后 ...

  2. Java并发基础01. 传统线程技术中创建线程的两种方式

    传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...

  3. windows/tomcat 修改java虚拟机JVM以utf-8字符集加载class文件的两种方式

      1.情景展示 做了这么长时间的java开发,但是,你知道JVM是以怎样的编码加载.解析class文件的吗? 我们知道,通常情况下,我们会将java文件的字符集修改成utf-8,这样,理所当然地就认 ...

  4. 基于Java使用Flink读取CSV文件,针对批处理,多表联合两种方式Table类和Join方法的实现数据处理,再入CSV文件

    Maven依赖 源头 <dependencies> <dependency> <groupId>org.projectlombok</groupId> ...

  5. Java 爬虫遇上数据异步加载,试试这两种办法!

    这是 Java 爬虫系列博文的第三篇,在上一篇 Java 爬虫遇到需要登录的网站,该怎么办? 中,我们简单的讲解了爬虫时遇到登录问题的解决办法,在这篇文章中我们一起来聊一聊爬虫时遇到数据异步加载的问题 ...

  6. 第二节:SSL证书的申请、配置(IIS通用)及跳转Https请求的两种方式

    一. 相关概念介绍 1. SSL证书服务 SSL证书服务由"服务商"联合多家国内外数字证书管理和颁发的权威机构.在xx云平台上直接提供的服务器数字证书.您可以在阿里云.腾讯云等平台 ...

  7. Java连接Neo4j的两种方式

    1.Neo4j数据库的两种方式 Neo4j可以以两种方式运行: Java应用程序中的嵌入式数据库 通过REST的独立服务器 不管哪一种方式,这个选择不会影响查询和使用数据库的方式. 它是由应用程序的性 ...

  8. 并发编程 ~~~ 多进程~~~进程创建的两种方式, 进程pid, 验证进程之间的空间隔离, 进程对象join方法, 进程对象其他属性

    一 进程创建的两种方式 from multiprocessing import Process import time def task(name): print(f'{name} is runnin ...

  9. JAVA发送http GET/POST请求的两种方式+JAVA http 请求手动配置代理

    java发送http get请求,有两种方式. 第一种用URLConnection: public static String get(String url) throws IOException { ...

  10. 两种方式实现java生成Excel

    Web应用中难免会遇到需要将数据导出并生成excel文件的需求.同样,对于本博客中的总结,也是建立在为了完成这样的一个需求,才开始去了解其实现形式,并且顺利完成需求的开发,先将实现过程总结于此.本博文 ...

随机推荐

  1. SmartBinding实现DataSet与ListView的绑定及同步显示

    kbmMW 5.10.10发布了,这个版本解决了我提出的问题,当对DataSet增删记录时,ListView能够同步显示.下面看看具体的实现代码. 为了解决上面的问题,作者为IkbmMWBinding ...

  2. Vue获取数据渲染完成事件

    主要代码是这两坨 this.nextTick(function(){ alert('数据已经更新') }); this.$nextTick(function(){ alert('v-for渲染已经完成 ...

  3. [GDOI2014]采集资源

    题目概述 题目描述 魔兽争霸3中,战略资源的采集通过使用农民.苦工.小精灵以及寺僧来进行. 在魔兽争霸4的开发中,玻璃渣觉得这种模式太过单一,于是他们想添加更多的单位来使采集的模式更加丰富. 在新的模 ...

  4. Java&Selenium数据驱动【DataProvider+TestNG+Excel】

    Java&Selenium数据驱动[DataProvider+TestNG+Excel] package testNGWithDataDriven; import java.io.File; ...

  5. 大数据之路week05--day02(Maven安装,环境变量的配置及基本使用)

    今天我们就来学习一下maven,怎么说呢,maven更像是一种管理的工具,实现的原理是使用插件. 举个例子,比如说,一个公司需要做一个项目,这个项目又分成了很多的模块,每个模块又分成了许多的业务等等, ...

  6. Selenium(十)测试用例错误处理、日志接口、多用户测试

    1.一般的错误类型 2.查看错误提示,是一个div,以id为例找到该元素 3.修改测试用例 def checkResult(driver,err_id): try: err = driver.find ...

  7. kubectl 自动补全

    kubectl 这个命令行工具非常重要,与之相关的命令也很多,我们也记不住那么多的命令,而且也会经常写错,所以命令自动补全是很有必要的,kubectl 工具本身就支持自动补全,只需简单设置一下即可. ...

  8. 2018VUE面试题总结

      Vue面试题 一:什么是MVVM MVVM是是Model-View-ViewModel的缩写,Model代表数据模型,定义数据操作的业务逻辑,View代表视图层,负责将数据模型渲染到页面上,Vie ...

  9. 前端面试题-HTML+CSS

    引用GitHub 上 ltadpoles的前端面试 https://github.com/ltadpoles HTML部分 1. Doctype作用,HTML5 为什么只需要写<!DOCTYPE ...

  10. pycharm分辨率&清晰度

    三个月前换了新电脑,安装pycharm.又换了新的大屏幕. pycharm界面拖到大屏上时,字大小和字体都没有变化,清晰度低了很多,就像打了一层薄薄的马赛克一样.拖回到原本的屏幕又清晰了. 一直以为是 ...