2012-08-10 24 views
3
public class ResLookupGetService extends Service { 
    ServerServicePortType getServerServicePort(); 
} 
public interface ServerServicePortType { 
    ServerServiceResponse doSoapMethod(RequestObject request, ParamObject parameters); 
} 

ServerServicePortType service = new ServerServiceGetService().getServerServicePort(); 
ServerServiceResponse response = service.doSoapMethod(request, parameters); 

上述代码在需要相互SSL加密之前可以正常调用我的SOAP服务。SOAP与相互SSL - 如何通过凭证发送?

一旦它打开,我尝试创建一个SSL上下文并设置它像这样:

ServerServicePortType service = new ServerServiceGetService().getServerServicePort(); 

BindingProvider bindingProvider = (BindingProvider) service; 
    bindingProvider.getRequestContext().put(
     "com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", 
     getSslContext().getSocketFactory()); 

ServerServiceResponse response = service.doSoapMethod(request, parameters); 

和代码来创建SSLContext

public SSLContext getSslContext(String keyStorePath, String keyStoreType, String trustStorePath) { 
    KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
    InputStream ksis = ClassLoader.getSystemResourceAsStream(keyStorePath); 
    keyStore.load(ksis, "mypassword".toCharArray()); 
    ksis.close(); 

    KeyStore trustStore = KeyStore.getInstance("JKS"); 
    InputStream tsis = ClassLoader.getSystemResourceAsStream(trustStorePath); 
    trustStore.load(tsis, "mypassword".toCharArray()); 
    tsis.close(); 

    TrustManagerFactory tmf = 
     TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmf.init(trustStore); 

    KeyManagerFactory kmf = 
     KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    kmf.init(keyStore, "mypassword".toCharArray()); 

    sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
    return sslContext; 
} 

但它似乎没有不正确传递我的凭证。我是否正确设置?

感谢

回答

2

事实证明,使用BindingProvider什么也不做(或至少我不能用它来一个点,这就不一样了)。

到电话调用Web服务之前,我简单地设置这些系统属性:

private void setSystemProps() { 

    String keyStoreFileName = "ssl/clientKeyStore.jks"; 
    String keyStorePath = ClassLoader.getSystemResource(keyStoreFileName).getPath(); 
    String keyStoreType = "JKS"; 
    String keyStorePassword = "mypassword"; 

    String trustStoreFileName = "ssl/clientTruststore.jks"; 
    String trustStorePath = ClassLoader.getSystemResource(trustStoreFileName).getPath(); 
    String trustStoreType = "JKS"; 
    String trustStorePassword = "mypassword"; 

    Properties systemProps = System.getProperties(); 
    systemProps.put("javax.net.ssl.keyStore", keyStorePath); 
    systemProps.put("javax.net.ssl.keyStorePassword", trustStorePassword); 
    systemProps.put("javax.net.ssl.keyStoreType", keyStoreType); 

    systemProps.put("javax.net.ssl.trustStore", trustStorePath); 
    systemProps.put("javax.net.ssl.trustStoreType", trustStoreType); 
    systemProps.put("javax.net.ssl.trustStorePassword", keyStorePassword); 
    System.setProperties(systemProps); 
    } 

然后,我可以做服务呼叫像正常:

ServerServicePortType service = new ServerServiceGetService().getServerServicePort(); 
ServerServiceResponse response = service.doSoapMethod(request, parameters); 

值得一提的是,当我设置了系统属性,他们接受任何Object作为值,并且我错误地将它设置为URL对象而不是String。

所以trustStorePathkeyStorePath变量被设置为.getPath()价值,这是一个绝对的文件路径,如:

"/Users/username/path/to/directory/with/ssl/clientKeyStore.jks" 

现在一切正常。