如何使用带有 SSL 的 httpclient 调用 SOAP Web 服务

Posted

技术标签:

【中文标题】如何使用带有 SSL 的 httpclient 调用 SOAP Web 服务【英文标题】:How to call SOAP web service use httpclient with SSL 【发布时间】:2018-10-24 21:04:35 【问题描述】:

现在请帮忙​​, 我想通过 SOAP 调用 api 并使用 httpclient 4.5.5

我的代码

static String callApi(String url, String requestXml)

    String responseXml = "";        
    CloseableHttpClient httpClient = null;
    HttpPost httpPost;
    try
    
        httpClient = HttpClients.createDefault();
        httpPost = new HttpPost(url);

        httpPost.setHeader("Content-Type", "text/xml; charset=utf-8");
        httpPost.setHeader("x-ibm-client-id", Config.csp.validKey);

        StringEntity entiry = new StringEntity(requestXml, "UTF-8");

        httpPost.setEntity(entiry);

        HttpResponse response = httpClient.execute(httpPost);

        HttpEntity entity = response.getEntity();
        responseXml = EntityUtils.toString(entity, "UTF-8");

    
    catch (Exception ex)
    
        log.error("", ex);
    
    finally
    
        try
        
            if (httpClient != null)
                httpClient.close();
        
        catch (Exception ex)
        
            log.error("", ex);
        
    
    return responseXml;

当我调试时显示错误

javax.net.ssl.SSLPeerUnverifiedException: 的证书与任何主题替代名称都不匹配:[*.domain.vn, domain.vn] 在 org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:467) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:397) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.5.jar:4.5.5] 在 org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.5.jar:4.5.5]

请帮忙。非常感谢

【问题讨论】:

我强烈建议您使用实际上是为 SOAP 设计的库(例如 CXF),而不是只为基本 HTTP 设计的库。至于您的错误:这看起来像是无效的 SSL 证书 看到这可能对你有帮助:***.com/questions/40806615/… 可能duplicate 非常感谢您的支持。 @Eugène Adell,是的,没错。我找到了我的问题的答案。谢谢。 【参考方案1】:

您没有显示您如何调用callApi(),但我猜您正在使用10.xx.xx.xx IP 地址而不是其证书中包含的名称之一来寻址您的主机。

当主机名验证生效时,您不能这样做。

您最好更改为通过其证书公用名或主题备用名称 (SAN) 之一对其进行寻址。但是,如果您不能这样做,并且由于10.* IP 地址范围是专用网络,您可能可以安全地关闭此服务器到服务器调用的主机名验证。

而不是这个...

httpClient = HttpClients.createDefault();

这样做...

httpClient = HttpClients
               .custom()
               .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
               .build();

根据您使用的 Apache HttpClient 版本,语法可能略有不同。

这会禁用安全控制。在您无法控制的网络上呼叫主机时不要这样做。

【讨论】:

谢谢,我在帖子中找到了答案(link

以上是关于如何使用带有 SSL 的 httpclient 调用 SOAP Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

Apache httpclient javax.net.ssl.SSLHandshakeException:

带有客户端证书的 HttpClient POST 请求

如何忽略 Apache HttpComponents HttpClient 5.1 中的 SSL 证书错误

如何接收httpclient发送的请求

带有 Microsoft TMG 代理 + HTTP Post + SSL 的 ApacheHttpClient 4.3.3 问题

使用 HttpClient 允许不受信任的 SSL 证书