未通过SSL使用客户端证书发出SOAP请求

时间:2016-03-18 06:08:28

标签: java ssl soap client-certificates

我无法通过SSL使用客户端证书成功发送SOAP请求。由于我有多个具有不同客户端证书的传出连接,我必须以编程方式处理密钥库。您可以在下面找到我的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>

1 个答案:

答案 0 :(得分:0)

来自Java 1.8u51 +,1.7.0_85 +和1.6.0_101 + Oracle更改了SSL证书的安全策略

我有同样的问题 试着这个:
我使用here的第1和第2课 来自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的类用于发送SOAP
制作自己的keyStore和trustStore
我通过IP连接,我使用别名键(它们在商店中相同)
它对我有用 PS:my other simple method不适用于SOAP((