okhttp连接池_OkHttp配置HTTPS访问+服务器部署
1 概述
OkHttp配置HTTPS访问,核心为以下三个部分: - sslSocketFactory() - HostnameVerifier - X509TrustManager
第一个是ssl套接字工厂,第二个用来验证主机名,第三个是证书信任器管理类.通过OkHttp实现HTTPS访问需要自己实现以上三部分.另外还简单提及了服务器端的部署,用的是Tomcat9,最后是一些常见问题的可能解决方案.
2 OkHttp介绍
OkHttp是一款开源的处理网络请求的轻量级框架,有Square公司贡献,用于替代HttpUrlConnection与Apache HttpClient,目前Github上有36.4k的star.优点有 - 共享socket,HTTP/2支持所有连接到同一个主机的请求共享socket - 连接池可以减少请求延迟 - 缓存响应数据减少重复的网络请求 - 自动处理gzip压缩
总的来说OkHttp是一款支持get/post请求,支持文件上传/下载的优秀的HTTP框架.
3 准备工作
- 一台服务器
- 一个域名
- 一个证书
什么?都没有?买! 当然证书可以不用买,可以使用openssl之类的工具生成,不过自签名的证书后面验证的时候会有点麻烦,建议还是购买.
4 OkHttp部分
4.1 暴力方案
public static String test() {OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts()).hostnameVerifier(new TrustAllHostnameVerifier()).build();String url = "https://xxxxxxx"; //修改成自己的urlRequest request = new Request.Builder().url(url).build();Call call = build.newCall(request);Response response = call.execute();if(response.body() != null){String result = response.body().string();//处理result}
}private static class TrustAllCerts implements X509TrustManager {public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
}private static class TrustAllHostnameVerifier implements HostnameVerifier {public boolean verify(String hostname, SSLSession session) { return true; }
}private static SSLSocketFactory createSSLSocketFactory() {SSLSocketFactory ssfFactory = null;try {SSLContext sc = SSLContext.getInstance("TLS");sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());ssfFactory = sc.getSocketFactory();} catch (Exception e) {e.printStackTrace();}return ssfFactory;
}
这是一种暴力的方案,看类名就知道了,信任所有的证书与主机:
public boolean verify(String hostname, SSLSession session) { return true; }
这个方法直接返回true,也就是信任所有的主机.
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
这里两个check函数没有做任何的工作,表示接受任意的客户端与服务端的证书.这样写的话相当于是使用了一个没用的TrustManager,这样还不如不加密,不推荐使用.
4.2 推荐方案
从两方面入手修改,一是从X509TrustManager入手,二是从HostnameVerifier入手.
4.2.1 HostnameVerifier
先说个简单的,这里主要是验证主机名,简单的话,可以如下实现:
HostnameVerifier hnv = new HostnameVerifier() {@Overridepublic boolean verify(String hostname, SSLSession session) {if("www.test.com".equals(hostname)){ return true; } else { HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();return hv.verify(hostname, session);}}
};
这里验证主机名是http://www.test.com就返回true,实现得比较简单,业务复杂的话可以结合配置中心,黑/白名单等动态校验.
4.2.2 X509TrustManager
这里其实有两种方式,一种是以流的方式添加信任证书:
private static X509TrustManager trustManagerForCertificates(InputStream in)throws GeneralSecurityException
{CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);if (certificates.isEmpty()) {throw new IllegalArgumentException("expected non-empty set of trusted certificates");}char[] password = "password".toCharArray(); // 这里可以使用任意密码KeyStore keyStore = newEmptyKeyStore(password);int index = 0;for (Certificate certificate : certificates) {String certificateAlias = Integer.toString(index++);keyStore.setCertificateEntry(certificateAlias, certificate);}// Use it to build an X509 trust manager.KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());keyManagerFactory.init(keyStore, password);TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());trustManagerFactory.init(keyStore);TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)){throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));}return (X509TrustManager) trustManagers[0];
}
完整代码见文末.这里把工具类的方法实现成了静态,调用时可以直接:
OKHTTP.send("https://xxxxx");
另一种方式是直接自定义一个TrustManager,重写里面的三个方法:
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[]{new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException {for (X509Certificate cert : chain) {// Make sure that it hasn't expired.cert.checkValidity();// Verify the certificate's public key chain.try {cert.verify(((X509Certificate) ca).getPublicKey());} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (NoSuchProviderException e) {e.printStackTrace();} catch (SignatureException e) {e.printStackTrace();}}}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}}
}, null);
第一个方法为
@Override
public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {}
该方法检查客户端的证书,由于不需要对客户端进行认证,默认即可. 第二个方法为
@Override
public void checkServerTrusted(X509Certificate[] chain,String authType)
该方法检查服务器的证书,若不信任该证书则抛出异常,通过自己实现该方法可以信任任何自己指定的证书,不做任何处理的话,不会抛出任何异常,相当于信任所有证书.这里检查了证书是否过期以及证书的签名是否匹配. 第三个方法为
@Override
public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];
}
返回受信任的X509证书数组.
这种方法笔者没有试过,仅供参考.
5 服务器部署
服务器用的是Tomcat,简单介绍一下部署.
5.1 上传工程
后端处理用的Spring Boot的工程,就不演示了,使用IDEA打成war包后上传到webapps下即可.
5.2 Tomcat配置
重点说一下Tomcat的配置,首先需要一个域名,修改conf/server.xml文件,找到默认的名叫localhost的Host:
然后直接复制Host标签,把name修改成自己的域名即可.
然后是证书的配置,笔者的证书在某某云上购买的,这里提供了几种格式的证书下载:
Tomcat的是两个文件,一个是pfx文件,一个是密码文件,把pfx文件上传到服务器的Tomcat后,继续修改server.xml,大约87行左右的位置(Tomcat版本9.0.33):
修改如下:
添加了scheme,secure,keystoreFile,keystoreType,keystorePass,clientAuth,sslProtocol配置,同时去掉里面的<SSLHostConfig>,keystoreFile是刚才的pfx文件,采用绝对路径,keystorePass是密码. 另外默认的端口为8443,这里修改成了8123. 重启Tomcat后输入
https://www.test.com:port
进行测试
这样就成功了.
6 验证与源码
这个因为没有完整的Demo很难做验证,具体来说前端用的OkHttp核心都介绍了,后端的话服务器Tomcat也介绍了,用Spring Boot做个Demo应该不难.
这里只给出了工具类OKHTTP的源码:
2293736867/OkHttp-HTTPS-demogithub.com
7 常见问题
7.1 Tomcat HTTPS无法访问
- 证书文件错误,不过这个可能性比较少.
- 配置错误,请检查配置文件是否正确,可以ps -ef | grep tomcat查看Tomcat是否开启以及查看logs/catalina.out日志.
- 端口错误,访问的端口需要与<Connector>中的端口对应(Tomcat默认的HTTPS端口为8443,笔者居然看成了8433,然后netstat 无数次都没有看到被监听...)
- 安全组/防火墙问题,云服务器的话需要在安全组配置中开启相应端口,同时应查看有没有把某个ip列入黑名单导致无法访问.防火墙的话这里主要指iptables,如果没有开启的话不需要理会,如果开启的话需要开放对应端口.
7.2 OkHttp HTTPS无法访问
- 无法读取证书文件:需要把证书文件放在工程对应路径下读取,比如AS中放在assets下然后使用getAssets().open("http://xxx.xxx")获取,Maven工程的话放在resources下直接使用FileInputStream获取.
- singed fields invalid:
证书文件格式错误,使用.crt/.pem等证书.
- Signature does not match:这个有可能是使用openssl自生成证书在验证的时候出现的异常,可能的解决办法是转换证书的格式,如果不行就重新生成一次证书.
8 参考链接
Android App 安全的HTTPS 通信pingguohe.netAndroid OkHttp实现HTTPS访问,支持Android 4.X系统HTTPS访问blog.csdn.net
Android使用OkHttp请求自签名的https网站www.jianshu.com
okhttp连接池_OkHttp配置HTTPS访问+服务器部署相关推荐
- okhttp 连接池_okhttp 源码分析
https://square.github.io/okhttp/square.github.iosquare/okhttpgithub.com 0 概述 okhttp是一个现代的网络请求框架 Ht ...
- 服务器连接池怎么配置文件,服务器连接池怎么配置
服务器连接池怎么配置 内容精选 换一换 本节操作以Windows Server 2012操作系统的云服务器为例介绍实现多用户登录的操作步骤.Windows server2012服务器默认能够支持两个用 ...
- 使用JavaBean封装对数据库的访问、连接池的配置和使用
目标: l 掌握如何共享连接数据库的代码: l 掌握PrepareSatement的使用: l 掌握数据库连接池的配置和使用: 主要内容: l ...
- WebSphere中连接池的配置
本来上午已经把这篇文章写好了,点击快速提交以后,提示输入用户名和密码,我还以为是长时间无操作就会掉线的,结果登录以后什么都没有了,呵呵,现在又要重新写一遍.没事,上午有很多地方没想到,下午会改正的. ...
- springboot添加多数据源连接池并配置Mybatis
springboot添加多数据源连接池并配置Mybatis 转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9190226.html May 12, 2018 ...
- weblogic oracle连接池配置文件,weblogic连接池的配置
Weblogic中访问oracle数据库的连接池可以采用三种JDBC方式进行配置 一 在weblogic console中按如下配置 建立connection pool ,并修改startWeblog ...
- 中间件 BES 连接池的配置和问题诊断方法
彭文元 云和恩墨技术专家 服务于某省移动公司BES中间件和数据库运维,在IT行业拥有10年以上的工作经历,包含产品开发.需求调研.数据库以及中间件的实施维护等.擅长 BES 中间件和 ORACLE 数 ...
- SSL证书配置(https访问接口, 单向认证和双向认证)
拿到SSL证书后, 如何才能解锁更多玩法? 一. SpringBoots项目配置https访问接口(直接配置) SSL协议 配置步骤 1. 获取证书/ 生成证书 2. 放置证书 3. 配置项目 pro ...
- Django配置Https访问
Django配置Https访问 问题描述 相关知识普及 什么是http? 什么是https? http vs https 问题解决 问题分析 解决方案 1 解决方案2 实际操作 验证 重启服务 请求验 ...
最新文章
- Java 中文转拼音
- PHP与SQL数据库交互中文乱码怎么办
- contract net with fipa
- 在Linux系统中构建虚拟网络
- Python中运算符 is 和 == 的区别
- 20172332 2017-2018-2 《程序设计与数据结构》第七周学习总结
- Codeforces #364 DIV2
- 3. Storm编程框架
- oracle异步sql,Oracle sqlplus登陆异步io错误
- 计算机操作系统-第二章复习题
- Appium+Python使用-模拟手机按键操作
- [高通SDM450][Android9.0]CTA认证--去掉录音功能
- 程序员转行量化交易可行吗?
- 3.抽象类(shape)
- 如何搭建一个自己的图床
- 计算机网络(七):网络安全
- 原码,反码,补码详解及原理
- 代码强力对比,就用这7个工具!
- win10下安装win7双系统
- Spring Security介绍(4)
热门文章
- AIX 上安装SSH
- Google推出Web开发利器:App Engine
- 在C#中使用Selenium WebDriver执行JavaScript
- cefSharp通过js操控页面,含跨域操控
- js 格式化日期 (/Date(1400046388387)/)
- javaweb学习总结(十一)——使用Cookie进行会话管理
- SELECT LAST_INSERT_ID() 的使用和注意事项
- 为PHP5.4开启Zend OPCode缓存
- Elasticsearch和MongoDB对比
- 谷歌新语言重写android,谷歌将推新设计语言 安卓APP用户界面将换新颜