一、解决方案

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. Android大牛的博客

    1 谦虚的天下:http://www.cnblogs.com/qianxudetianxia/ 2 csdn博文精选:http://www.csdn.net/article/2011-08-30/30 ...

  2. 提高比特率 有损 无损 Video-and-Audio-file-format-conversion 视频声音转码

    3 Ways to Change Bitrate on MP3 Files https://www.online-tech-tips.com/software-reviews/change-bitra ...

  3. 如何快速定位JVM中消耗CPU最多的线程? Java 性能调优

    https://mp.weixin.qq.com/s/ZqlhPC06_KW6a9OSgEuIVw 上面的线程栈我们注意到 nid 的值其实就是线程 ID,它是十六进制的,我们将消耗 CPU 最高的线 ...

  4. Posting array of JSON objects to MVC3 action method via jQuery ajax

    Does the model binder not suport arrays of JSON objects? The code below works when sending a single ...

  5. SoapUI中读取Office365邮件

    常见邮件服务一般使用IMAP邮件访问协议,如果你所在公司更换到Office 365则需要另一个组件. Office 365使用的是Exchange Server电子邮件服务组件,需要微软的Jar包来支 ...

  6. camera闪光灯校准

    1. adb shell 2. setprop z.flash_ratio 1 3. 全黑环境下,请将手机固定,对着白墙10cm,固定. 4. 点击拍照,然后手机会自动打闪2(Duty num)次(其 ...

  7. I.MX6 Battery issues

    /******************************************************************** * I.MX6 Battery issues * 说明: * ...

  8. STM32F4 DMA2D_R2M

    图像处理的专门DMA 看一段示例代码 /** * @brief Displays a line. * @param Xpos: specifies the X position. * @param Y ...

  9. 【192】PowerShell 相关知识

    默写说明: 查询别名所指的真实cmdlet命令. Get-Alias -name ls 查看可用的别名,可以通过 “ls alias:” 或者 “Get-Alias”. 查看所有以Remove打头的c ...

  10. ObjectInputStream与ObjectOutputStream类实现对象的存取

    1. ObjectInputStream与ObjectOutputStream类所读写的对象必须实现Serializable接口,对象中的transient和static类型成员变量不会被读取和写入 ...