java - 无法通过带有客户端证书的 SSL 发出 SOAP 请求

标签 java ssl soap client-certificates

我无法通过带有客户端证书的 SSL 发出成功的 SOAP 请求。由于我有多个与不同客户端证书的传出连接,因此我必须以编程方式处理 keystore 。您可以在下面找到我的 Java 代码。

如果我设置 -Djavax.net.debug=all 我会在日志中找到这一行:

Warning: no suitable certificate found - continuing without client authentication

这很明显,但我不知道为什么会这样。有什么问题或如何调试吗?

    SSLContext sc = SSLContext.getInstance("SSL");
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    KeyStore ks = KeyStore.getInstance("JKS");
    InputStream is = getClass().getResourceAsStream("/path_to_client_certificate.p12");

    Assert.assertNotNull(is);

    ks.load(is, "my_password".toCharArray());
    kmf.init(ks, "my_password".toCharArray());
    sc.init(kmf.getKeyManagers(), null, null);
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    URL url = getClass().getClassLoader().getResource("/path_to_local_wsdl_file.wsdl");
    BillingService billingService = new BillingService(url);
    BoBillingService boBillingService = billingService.getWsHttp();

    BindingProvider bindingProvider = (BindingProvider) boBillingService;
    bindingProvider.getRequestContext()
            .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                    "https://www.hostname.com/service_path");

    ExecutePingOut executePingOut = boBillingService.executePing("My Text", true);

    LOGGER.trace(executePingOut.getMessage().getValue());

运行这段代码会得到以下输出:

---[HTTP request - https://www.hostname.com/service_path]---
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: "https://www.hostname.com/service_path/ExecutePing"
User-Agent: JAX-WS RI 2.2.8 svn-revision#13980
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
    <ExecutePing xmlns="https://www.hostname.com/service_path" xmlns:ns2="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:ns3="http://schemas.datacontract.org/2004/07/EBS.BO.Billing">
    <text>My Text</text>
    <exceptionTest>true</exceptionTest>
</ExecutePing>
</S:Body>
</S:Envelope>--------------------


---[HTTP response - https://www.hostname.com/service_path - 500]---
null: HTTP/1.1 500 Internal Server Error
Connection: close
Content-Length: 311
Content-Type: text/xml; charset=utf-8
Date: Fri, 18 Mar 2016 05:31:31 GMT
Server: Apache (proxied)
Set-Cookie: ittrksessid=6d564320.52e4c0f3a5ec0; path=/; domain=.hostname.ch
Strict-Transport-Security: max-age=15768000
Vary: Accept-Encoding
X-Frame-Options: SAMEORIGIN
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
    <s:Fault>
        <faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:FailedAuthentication</faultcode>
        <faultstring xml:lang="de-CH">Access is denied.</faultstring>
    </s:Fault>
</s:Body>
</s:Envelope>

最佳答案

从 Java 1.8u51+、1.7.0_85+ 和 1.6.0_101+ 开始,Oracle 更改了 SSL 证书的安全策略

我也有同样的问题
试试这个:
我使用 here 中的第一和第二类
来自 ASIX 的 HostnameVerifier 类作为

    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return fias.HostnameVerifier.DEFAULT.verify(hostname, session);
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(hv);
    HttpsURLConnection con = (HttpsURLConnection) new URL(url).openConnection();
    con.connect();

和来自 here 的类(class)用于发送 SOAP
制作你自己的 keyStore 和 trustStore
我通过 IP 进行连接,并为 key 使用别名(它们在商店中相同)
它对我有用
附:my other simple method尚不适用于 SOAP ((

关于java - 无法通过带有客户端证书的 SSL 发出 SOAP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36077302/

相关文章:

javascript - 使用 --ignore-ssl-errors=true 从 casperjs 运行 phantomjs

ssl - AWS - 负载均衡器上的 SSL/HTTPS

perl - 用 WSDL 描述 Perl 接口(interface)

java - WebView 不重新加载具有相同 URL 的页面

java - 如何更换|| (两个管道)来自带有 | 的字符串(一)管道

Java - ImageIcon不会显示图像

java - 如何在java中读取使用python的struct.pack方法编写的字符串

.net - 我可以在 Azure 上为常规网站设置 SSL吗? (不是 WCF 或 MVC)

c++ - ONVIF 身份验证错误?

web-services - 将自定义 Http header 添加到 Web 服务代理