一、解决方案

1、httpClient请求https版蓝鲸接口

(1)、原理

https与http最大的区别在于SSL加密传输协议的使用。在自己写的JAVA HttpClient程序,想手动验证证书,可以在客户端绕过验证服务器证书的步骤,即则需要实现空的X509TrustManager接口。

类中的验证方法返回void或者null,是为了绕过验证。正常的方法体如果检验出证书无法被信任,需要手动抛出异常:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building

failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

并在chtch中处理异常,如果想要绕过验证,也就是说不要抛出异常就可以了,可以理解为信任了任何证书。

(2)、代码展示:HttpsClientUtil.java

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
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 javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
/**
* @author xiehaiqing
* @date 2019/03/26
*/
public class HttpsClientUtil {
/**
* 在调用SSL之前需要重写验证方法,取消检测SSL
* 创建ConnectionManager,添加Connection配置信息
* @return HttpClient 支持https
*/
public static HttpClient sslClient(){
try {
// 在调用SSL之前需要重写验证方法,取消检测SSL
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException { }
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException { }
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
ctx.init(null, new TrustManager[]{trustManager}, null);
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
//创建registry
RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT)
.setExpectContinueEnabled(Boolean.TRUE).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", socketFactory).build();
// 创建ConnectionManager,添加Connection配置信息
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).build();
return closeableHttpClient;
}catch (KeyManagementException ex){
throw new RuntimeException(ex);
}catch (NoSuchAlgorithmException e){
throw new RuntimeException(e);
}
} /**
* post请求
* @param url
* @param jsonStr
* @return
*/
public static String doPost(String url,String jsonStr){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
httpClient = sslClient();
httpPost = new HttpPost(url);
httpPost.addHeader("Content-type","applicattion/json");
StringEntity se = new StringEntity(jsonStr);
se.setContentType("text/json");
se.setContentEncoding(new BasicHeader("Content-type","application/json"));
httpPost.setEntity(se);
HttpResponse response = httpClient.execute(httpPost);
if (response !=null){
HttpEntity entity = response.getEntity();
if (entity !=null){
result = EntityUtils.toString(entity,"utf-8");
}
}
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}

展开源码

2、模拟https版本登录

(1)、原理

icube模拟登陆,即是通过服务的登录链接,对用户输入的账号密码进行真实的验证,本功能使用了Jsoup解析的方式实现。

具体逻辑为,先使用get请求链接的方式,生成登录所需的bklogin_csrftoken这一属性字段,然后在通过post携带用户输入的账号密码和该csrftoken字段进行登录请求,如果用户输入的账号密码正确,则在cookie中会有一个不为空的bk_token字段,即为登录成功,否则登录失败。对于https请求,需要在请求之前绕过证书验证,这里采用创建不验证证书链的信任管理器来实现。

登录链接示例:https://xx.com/login/?c_url=

(2)代码展示

 import com.zork.opbd.datasource.Config;

 import com.zork.opbd.log.SystemLogHelper;

 import org.jsoup.Connection;

 import org.jsoup.Connection.*;

 import org.jsoup.Jsoup;

 import org.jsoup.nodes.Document;

 import org.jsoup.nodes.Element;

 import org.jsoup.select.Elements;

 import javax.net.ssl.*;

 import java.security.KeyManagementException;

 import java.security.NoSuchAlgorithmException;

 import java.security.SecureRandom;

 import java.security.cert.CertificateException;

 import java.security.cert.X509Certificate;

 import java.util.*;

 public class BKLoginUtils {

     public static String LOGIN_URL= Config.getInstance().BK_LOGIN_URL; //https://xx.com/login/?c_url=

     public final static String USER_AGENT="User-Agent";

     public final static String USER_AGENT_VALUE="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36";

     public final static String LOGINFORM = "#login-form";

     public final static String NAME = "name";

     public final static String VALUE = "value";

     public final static String USERNAME = "username";

     public final static String PASSWORD = "password";

     public final static String ID = "id";

     public final static String USER = "user";

     public final static String REFERER = "Referer";

     public final static String BKTOKEN = "bk_token";

     public static void main(String[] args) throws Exception {

         boolean admin = siMulateLogin("admin", "zork.8888");

         System.out.println(admin);

     }

     /**

      * 模拟登陆功能

      * @param userName

      * @param pwd

      * @return result

      */

     public static boolean siMulateLogin(String userName,String pwd){

         boolean result = false;

         try{

             checkQuietly();

             Connection con = Jsoup.connect(LOGIN_URL).timeout(30000).userAgent(USER_AGENT_VALUE);

             Response rs = con.execute();

             Document doc = Jsoup.parse(rs.body());

             List<Element> elements = doc.select(LOGINFORM);

             Elements allElements = elements.get(0).getAllElements();

             Iterator<Element> iterator = allElements.iterator();

             Map<String,String> datas = new HashMap<>();

             while (iterator.hasNext()){

                 //赋值

                 Element element = iterator.next();

                 if (element.attr(NAME).equals(USERNAME) && element.attr(ID).equals(USER)){

                     element.attr(VALUE,userName);

                 }

                 if (element.attr(NAME).equals(PASSWORD) && element.attr(ID).equals(PASSWORD)){

                     element.attr(VALUE,pwd);

                 }

                 //排除空值表单属性

                 if (element.attr(NAME).length()>0){

                     datas.put(element.attr(NAME),element.attr(VALUE));

                 }

             }

             Connection conn = Jsoup.connect(LOGIN_URL);

             conn.header(USER_AGENT,USER_AGENT_VALUE);

             conn.header(REFERER,LOGIN_URL);//注意,这一行必须要加,否则会验证失败

             Response login = conn.ignoreContentType(true).followRedirects(true).method(Method.POST).data(datas).cookies(rs.cookies()).execute();

             Map<String,String> cookies = login.cookies();

             Iterator<String> keyIter = cookies.keySet().iterator();

             while (keyIter.hasNext()){

                 String key = keyIter.next();

                 if (BKTOKEN.equals(key)){

                     if (!StringUtil.isNull(cookies.get(key))){

                         SystemLogHelper.info("获取bk_token成功,bk_token:"+cookies.get(key),true);

                         result = true;

                     }else {

                         SystemLogHelper.info("获取bk_token失败,登陆失败,请检查用户名或密码",true);

                     }

                 }

             }

         }catch (Exception e){

             e.printStackTrace();

         }

         return result;

     }

     /**

      * 信任管理器

      * 绕过证书验证

      */

     public static void checkQuietly(){

         try{

             //创建不验证证书链的信任管理器

             TrustManager[] trustAllCerts = {

                     new X509TrustManager() {

                         @Override

                         public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                         }

                         @Override

                         public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                         }

                         @Override

                         public X509Certificate[] getAcceptedIssuers() {

                             return null;

                         }

                     }

             };

             //安装所有的信任管理器

             SSLContext ssl = SSLContext.getInstance("SSL");

             ssl.init(null,trustAllCerts,new SecureRandom());

             HttpsURLConnection.setDefaultSSLSocketFactory(ssl.getSocketFactory());

             //不验证主机名

             HostnameVerifier hv = new HostnameVerifier() {

                 @Override

                 public boolean verify(String s, SSLSession sslSession) {

                     return true;

                 }

             };

             HttpsURLConnection.setDefaultHostnameVerifier(hv);

         } catch (NoSuchAlgorithmException | KeyManagementException e) {

             e.printStackTrace();

         }

     }

 }

http升级https改造方案的更多相关文章

  1. CAS进行https到http的改造方案,结合cookie源码分析

    先说具体的改造方案: 服务端: 一.CAS Server端的修改 1.找到cas\WEB-INF\deployerConfigContext.xml 对以下Bean增加参数p:requireSecur ...

  2. 升级Https前的可行性验证(一)

    升级Https之前的可行性验证 注意:自签证书和Nginx的安装都基于ContOS 6 一.如何申请OpenSSL自签证书 1.安装OpenSSL (一)OpenSSL 工具下载 下载地址 (二)Op ...

  3. iOS 升级HTTPS通过ATS你所要知道的

    由于苹果规定2017年1月1日以后,所有APP都要使用HTTPS进行网络请求,否则无法上架,因此研究了一下在iOS中使用HTTPS请求的实现.网上搜索了一些比较有用资料,大家可以参考下 苹果强制升级的 ...

  4. iOS升级HTTPS通过ATS你所要知道的

    由于苹果规定2017年1月1日以后,所有APP都要使用HTTPS进行网络请求,否则无法上架,因此研究了一下在iOS中使用HTTPS请求的实现.网上搜索了一些比较有用资料,大家可以参考下 苹果强制升级的 ...

  5. Abp vNext异常处理的缺陷/改造方案

    吐槽Abp Vnext异常处理! 哎呀,是一个喷子 目前项目使用Abp VNext开发,免不了要全局处理异常.提示服务器异常信息. 1. Abp官方异常处理 Abp项目默认会启动内置的异常处理,默认不 ...

  6. 超详细网站博客域名和二级域名、子域名升级HTTPS免费申请SSL证书配置nginx指南

    随着互联网的飞速发展,我们的工作生活已经离不开互联网,HTTP虽然使用极为广泛, 但是存在不小的安全缺陷, 主要是其数据的明文传送和消息完整性检测的缺乏, 而这两点恰好是网络支付,网络交易等网站应用中 ...

  7. 为什么非全站升级HTTPS不可?

    升级HTTPS已经是大势所趋,但仍有大量互联网企业犹豫是否要全站升级HTTPS,为此本文梳理了全站升级HTTPS与部分升级HTTPS的优劣势对比,来判断是否真的有必要进行全站HTTPS升级. HTTP ...

  8. 阿里云免费购买SSL证书,nginx无缝升级https

    最近在升级交流学习社区,觉得有必要升级成https.以下是自己在升级中记录. 以下包括以下部分: 一.阿里云免费购买SSL证书 1.自己在阿里云申请了免费的,然后自己支付0元,购买了SSL证书 2.我 ...

  9. 网站HTTP升级HTTPS完全配置手册

    本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 今天,所有使用Google Chrome稳定版的用户迎来了v68正式 ...

随机推荐

  1. NYOJ110 剑客决斗

    剑客决斗 来源:Polish Olympiad in Informatics(波兰信息学奥林匹克竞赛) 时间限制:5000 ms  |  内存限制:65535 KB 难度:5   描述 在路易十三和红 ...

  2. redirect和rewrite

    1 服务器端重定向 客户端想要访问的内容不在该服务器上,该服务器自己去另外的服务器请求到该内容,然后还是由该服务器将内容返回给客户端.称为rewrite. 2 客户端重定向 客户端想要访问的内容不在该 ...

  3. 什么是 jQuery EasyUI

    jQuery EasyUI 是一个基于 jQuery 的框架,集成了各种用户界面插件. jQuery EasyUI 框架提供了创建网页所需的一切,帮助您轻松建立站点. easyui 是一个基于 jQu ...

  4. 每天进步一点点—mysql-mysqldump

    一.        简单介绍 mysqldump是client用来备份数据库或者在不通数据库之间进行数据迁移的工具,备份内容包括创建表或者装载表的SQL语句 二.       命令格式   备份单个数 ...

  5. POJ1236 Network of Schools —— 强连通分量 + 缩点 + 入出度

    题目链接:http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Tot ...

  6. AutoIT: 如何设置GUICtrlCreateCombo选项为不可修改状态

    GUICtrlCreateCombo中选中的选项是可修改的,也可设置为不可修改状态. #include<ComboConstants.au3> GUICtrlCreateLabel(, , ...

  7. 第十八周 Leetcode 72. Edit Distance(HARD) O(N^2)DP

    Leetcode72 看起来比较棘手的一道题(列DP方程还是要大胆猜想..) DP方程该怎么列呢? dp[i][j]表示字符串a[0....i-1]转化为b[0....j-1]的最少距离 转移方程分三 ...

  8. 解析javascript变量

    //add by tim//提供解析javascript 脚本的变量集合 using System;using System.Collections.Generic;using System.Linq ...

  9. char-rnn-tensorflow源码解析及结构流程分析

    char-rnn-tensorflow由飞飞弟子karpathy编写,展示了如何用tensorflow来搭建一个基本的RNN(LSTM)网络,并进行基于char的seq2seq进行训练. 数据读取部分 ...

  10. Go基于协程的归并排序简单实现

    归并排序这个可能很多人都不知道,今天用Go语言简单的实现下,其他语言可能要基于线程来实现. //产生一个源 func ArraySource(a ...int) chan int{ out :=mak ...