zoukankan      html  css  js  c++  java
  • 使用HttpClient携带pfx证书调用HTTPS协议的WebService

    调用第三方服务时,厂商提供了一个WSDL文件、调用的地址和一个后缀为pfx的证书文件,通过SOUPUI记载证书是可以正常调用WebService服务,那么如何将该服务转换为代码呢?

    咨询了厂商的支持,厂商说直接发送报文即可。

    观察SOUPUI的调用发现直接发送的SOUP报文,那么决定使用HttpClient进行服务调用,调用HTTPS好说、发送报文也好说,关键问题卡在了pfx证书上面。

    百度了很多例子,说JAVA无法直接携带pfx的证书,那么就在pfx证书转换方面尝试了一些,最终没有转换成功。

    继续观察SOUPUI的调用模式,SOUPUI可以在PERFERENCE的SSL中可以直接配置keystore和password,就可以携带证书,而且SOUPUI调用各种服务主要是使用HTTPClient完成的的,他可以实现,那就说明通过HTTPClient是可以直接携带pfx格式的证书的,基本思路确定,那就全力在这条路上继续折腾吧。

    整理一下尴尬的情况:

    资源:HTTPS协议、WebService服务、需要pfx证书认证;

    目标:通过HttpClient构建SSL通道调用HTTPS的WebService接口,携带pfx证书信息,直接发送SOUP报文调用接口;

    难点:pfx证书如何处理?

    百度了好久,有相应的解决方案,但实验后均不行;后在bing的国际版中进行搜索,结果中stackoverflow中有了大收获。

    地址:https://stackoverflow.com/questions/44493040/apache-httpclient-pfx-file

    该国际友人碰到了和我一样的问题,通过SOUPUI携带pfx证书调用Https的WebService服务没有问题,使用HttpClient模拟报文的时候无法携带证书,但是该哥们自行解决了该问题,而且还无私的把源代码整个贴在了论坛上,我用颤抖的双手复制粘贴了该代码,稍作修改执行发现问题解决。天哪,折腾了一个下午加晚上,终于算是解决了。

    在此特意转发一下这位大神的佳作:

    KeyStore clientStore  = KeyStore.getInstance("PKCS12"); 
    InputStream instream = Thread.currentThread().getContextClassLoader().getResourceAsStream(keystoreName);
    try {
        clientStore.load(instream, keyStorePwd.toCharArray());
    } finally {
        instream.close();
    }
    //Trust everybody
    X509TrustManager tm = new X509TrustManager() {
        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException {}
        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException {}
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
    };
    SSLContext sslCtx = SSLContext.getInstance("TLS");
    KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmfactory.init(clientStore, keyStorePwd != null ? keyStorePwd.toCharArray() : null);
    KeyManager[] keymanagers = kmfactory.getKeyManagers();
    sslCtx.init(keymanagers, new TrustManager[]{tm}, null);
    SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(sslCtx);
    Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("https", sslConnectionFactory).register("http", new PlainConnectionSocketFactory()).build();
    PoolingHttpClientConnectionManager pcm = new PoolingHttpClientConnectionManager(registry);
    HttpClientBuilder hcb = HttpClientBuilder.create();
    hcb.setConnectionManager(pcm);
    CloseableHttpClient httpClient = hcb.build();
  • 相关阅读:
    node体验
    JS练习--prototype的一道题目
    JS的OOP--继承之prototype
    JS的OOP--new一个function背后的实际操作
    JS中new运算符的运算顺序
    thymeleaf 拼接字符串与变量
    spring jpa exists
    LocalDateTime json格式化
    格式化java8 LocalDateTime
    springboot定时任务
  • 原文地址:https://www.cnblogs.com/xusweeter/p/7659762.html
Copyright © 2011-2022 走看看