2012-04-02 103 views
2

使用NetBeans 7.0.1开发应用程序,可以通过安全(HTTPS/SSL)SOAP与服务器/ web服务进行通信。 在NetBeans中,我只需单击“新建” - >“Web服务客户端...”,选择一个wsdl文件,然后单击完成。这将生成SOAP-Client的源代码。在那之后,我有一个自己的文件夹了许多新的Java文件:Java SOAP客户端JAX-WS:如何使用证书

Generated Sources (jax-ws) 

我改变了WSDL文件连接到自己的/本地主机没有HTTPS/SSL测试SOAP客户端,它似乎运作良好,但现在我需要为SOAP/HTTP连接使用特定的证书,至此我得到了.p12文件。

我不知道如何结合生成的来源使用证书。我使用生成的SOAP客户端是这样的:

SoapServiceExample SSA = new ClassSoapServiceExample(); 
Object Response = SSA.getServicePort().doSomething(Authentification, Data); 

,如果我尝试使用SOAP客户端与不变/正确的WSDL文件,我得到这个错误:

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

[com.sun.xml.internal.ws.transport.http.client.HttpClientTransport] [getOutput] [-1] 
[com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe] [process] [-1] 
[com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe] [processRequest] [-1] 
[com.sun.xml.internal.ws.transport.DeferredTransportPipe] [processRequest] [-1] 
[com.sun.xml.internal.ws.api.pipe.Fiber] [__doRun] [-1] 
[com.sun.xml.internal.ws.api.pipe.Fiber] [_doRun] [-1] 
[com.sun.xml.internal.ws.api.pipe.Fiber] [doRun] [-1] 
[com.sun.xml.internal.ws.api.pipe.Fiber] [runSync] [-1] 
[com.sun.xml.internal.ws.client.Stub] [process] [-1] 
[com.sun.xml.internal.ws.client.sei.SEIStub] [doProcess] [-1] 
[com.sun.xml.internal.ws.client.sei.SyncMethodHandler] [invoke] [-1] 
[com.sun.xml.internal.ws.client.sei.SyncMethodHandler] [invoke] [-1] 
[com.sun.xml.internal.ws.client.sei.SEIStub] [invoke] [-1] 
[$Proxy31] [doSomething] [-1] 

林已经能加载.p12证书以将其用于套接字。

public static TrustManager[] createTrustManagerWhoTrustAllways() 
{ 
    return new TrustManager[] 
    { 
     new X509TrustManager() 
     { 
      @Override 
      public X509Certificate[] getAcceptedIssuers() 
      { 
       return null; 
      } 

      @Override 
      public void checkClientTrusted(X509Certificate[] certs, String authType) 
      { 
       return; 
      } 

      @Override 
      public void checkServerTrusted(X509Certificate[] certs, String authType) 
      { 
       return; 
      } 
     } 
    }; 
} 

public static SSLContext loadPkcs12CertificateAndGetSslContext(String FileName, String Password) throws Exception 
{ 
    KeyStore KS = KeyStore.getInstance("PKCS12"); 
    KS.load(new FileInputStream(FileName), Password.toCharArray()); 

    KeyManagerFactory KMF = KeyManagerFactory.getInstance("SunX509"); 
    KMF.init(KS, Password.toCharArray()); 

    SSLContext SSLC = SSLContext.getInstance("TLS"); 
    SSLC.init(KMF.getKeyManagers(), createTrustManagerWhoTrustAllways(), new SecureRandom()); 

    return SSLC; 
} 

public void connect() throws Exception 
{ 
    if(true == m_Secure) 
    { 
     SSLContext SSLC = loadPkcs12CertificateAndGetSslContext(m_CertificateFileName, m_CertificatePassword); 

     m_Socket = SSLC.getSocketFactory().createSocket(m_ServerName, m_ServerPort); 
    } 
    else 
    { 
     m_Socket = new Socket(m_ServerName, m_ServerPort); 
    } 
} 

我知道/想这是不是写得很好来源,我相信它的可怕做法是使用这样的东西createTrustManagerWhoTrustAllways(),但即时通讯新的Java和我的第一个目标是产生工作的客户,如果我有考虑到这个障碍,我将专注于更安全的源代码。

有人可以告诉我,我如何为生成的SOAP客户端使用证书?

回答

1

你可以通过你的程序的命令行上提供通过系统属性的密钥库和信任配置声明一个全系统的密钥库:

-Djavax.net.ssl.trustStore=<yourtruststore> 
-Djavax.net.ssl.trustStorePassword=<pwd> 
-Djavax.net.ssl.keyStore=<your-keystore> 
-Djavax.net.ssl.keyStorePassword=<pwd> 

JAX-WS将拿起这个密钥库配置SSL客户端连接。只要确保你的密钥库中有适当的证书。