Soap SSL握手

4

我的客户成功通过HTTP从服务器获取响应。

SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
SOAPConnection connection = sfc.createConnection();

SOAPMessage soapMessageResponse = connection.call(soapRequest, new URL(serviceLocation));

我希望客户端和服务器之间进行SSL通信。

在另一个项目中,我成功地从一个KeyStore和TrustManagerFactory创建了SSLSocketFactory来完成SSL握手。

如何在webservice客户端中使用SSLSocketFactory代码,以使客户端能够成功进行SSL通信并调用服务器。

3个回答

1

我相信它将使用默认的SSLContext。 您可以使用SSLContext.setDefault()更改它。

SSLContext c = SSLContext.getInstance("SSL");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(yourKeystore);
TrustManager tm = tmf.getTrustManagers()[0];
tm.
c.init(null, tm, null);

以下是一些针对上述字符串参数的其他值

如果您需要更完整的控制权,可以实现自己的 SSLContext 子类,该子类返回您自己的 SSLSocketFactory 实现,并将该 SSLContext 设置为默认值:

public class MySSLContext extends SSLContext {

    private SSLContext wrapped;
    private SSLSocketFactory mySocketFactory;

    public MySSLContext(SSLContext toWrap, SSLSocketFactory mySocketFactory) {
        wrapped = toWrap;
        this.mySocketFactory = mySocketFactory;
    }

    public SSLSocketFactory getSocketFactory() {
        return mySocketFactory;
    }

    public SSLSessionContext getClientSessionContext() {
        return wrapped;
    }

    // other delegates

}

顺便说一下,我讨厌像这样的API,它只允许您在每个VM上同时拥有一个实例处于活动状态。在API中,静态变量的唯一可接受用途是工厂方法和常量。 - John Watts
我正在这样做。但是在SOAP客户端代码中应该在哪里使用这个SSLContext?正如我在问题中所讨论的那样,我正在从SSLContext构建SSLSocketFactory。 - Muhammad Imran Tariq
1
就像我之前所说的,我认为你在SSLContext.setDefault()上设置的任何内容都将被SOAPConnectionFactory使用。如果你想让SSLContext使用你的SSLSocketFactory,你需要子类化SSLContext。我建议上面提到的委托实现应该可以解决问题。 - John Watts
1
这就是我的第一条评论的意义所在。这是一个糟糕的API设计。Java对SOAPConnection的实现是HttpSOAPConnection。HttpSOAPConnection调用URL.openConnection。URL.openConnection使用URL.setURLStreamHandlerFactory提供的值。它被设置为HttpsURLConnectionImpl,它调用HttpsURLConnection,然后调用SSLSocketFactory.getDefault()。这是一个巨大的主要由静态方法构成的链。你只能全局修改它。理论上,你可以解开整个混乱并设置自己的URLStreamHandlerFactory。相信我,除非你绝对必须这样做,否则你不想这样做。 - John Watts
这真的会很混乱。因为我可以创建SSLSocketFactory,请在创建此工厂后给我提供一个示例代码。 - Muhammad Imran Tariq
显示剩余3条评论

0

你好,如果你在你的 Web 服务类中添加这段代码,我认为你的问题会得到解决。

     `

   //just put it your somewhere 
 public static class miTM implements javax.net.ssl.TrustManager,
    javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
}

public boolean isServerTrusted(
        java.security.cert.X509Certificate[] certs) {
    return true;
}

public boolean isClientTrusted(
        java.security.cert.X509Certificate[] certs) {
    return true;
}

public void checkServerTrusted(
        java.security.cert.X509Certificate[] certs, String authType)
        throws java.security.cert.CertificateException {
    return;
}

public void checkClientTrusted(
        java.security.cert.X509Certificate[] certs, String authType)
        throws java.security.cert.CertificateException {
    return;
}
    }





 // CAll This function in your webservice class .
private static void trustAllHttpsCertificates() throws Exception {

// Create a trust manager that does not validate certificate chains:

javax.net.ssl.TrustManager[] trustAllCerts =

new javax.net.ssl.TrustManager[1];

javax.net.ssl.TrustManager tm = new miTM();

trustAllCerts[0] = tm;

javax.net.ssl.SSLContext sc =

javax.net.ssl.SSLContext.getInstance("SSL");

sc.init(null, trustAllCerts, null);

javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(

sc.getSocketFactory());

    }

这意味着Web服务信任所有SSL证书而不进行检查,这在生产服务中可能不是一个好主意。 - Terry Horner

-2

这行代码在 SSL 的情况下无法工作。

SOAPMessage soapMessageResponse = connection.call(soapRequest, new URL(serviceLocation));

这里创建TrustManager和KeyManagers。

为了通过SSL从Axis2 Web服务获得响应,您需要像这里提供的那样打开流。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接