我们有一个SOAP-webservice,我们正在尝试通过具有用户名/密码连接的https-connection设置获取与该服务器的连接,而不涉及证书。看来Java仍在尝试并失败证书握手。如何设置连接以使其能够使用用户名/密码?
尝试在MyWeb上进行查询调用时生成错误:
2012-08-29 13:31:19,918 WARN (LogUtils.java:371) - Interceptor for {http://myaddress/}MyWebService#{http://myqname/}getStatus has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:510)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:440)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:343)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:295)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
at $Proxy55.getTccStatus(Unknown Source)
at se.transrail.cato.monitor.server.MonitorWsClient.readTccStatus(MonitorWsClient.java:65)
at se.transrail.cato.monitor.server.WebServicePoller.run(WebServicePoller.java:73)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://myaddress/: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1404)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1389)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:623)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 18 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1338)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1090)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1337)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1283)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:42)
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1361)
... 21 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1320)
... 37 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
... 43 more
MyWeb和MyWebService由Apache CXF 2.4.8 wsdl2java生成。 MyWeb是MyWebService的接口。
在myweb.wsdl中,我替换了
建立:
private MyWeb preparePort() {
MyWebService ss = new MyWebService(
// locally stored wsdl to avoid connection at this time
getClass().getClassLoader().getResource("myweb.wsdl");,
new QName("http://qname/", "MyWebService"));
MyWeb port = ss.getMonitorWebServicePort();
Client cl = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) cl.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(connectionTimeout);
httpClientPolicy.setReceiveTimeout(receiveTimeout);
httpClientPolicy.setConnection(ConnectionType.CLOSE);
httpClientPolicy.setMaxRetransmits(1);
http.setClient(httpClientPolicy);
((BindingProvider) port).getRequestContext().putAll(of(
USERNAME_PROPERTY, username,
PASSWORD_PROPERTY, password,
ENDPOINT_ADDRESS_PROPERTY, "https://mywebaddress/"));
return port;
从myweb.wsdl
<wsdl:service name="MyWebService">
<wsdl:port binding="tns:MyWebServiceSoapBinding" name="MyWebPort">
<soap:address location="https://mywebaddress/"/>
</wsdl:port>
</wsdl:service>
尝试在网上找到无法解决的修复程序:
// AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
// authorizationPolicy.setUserName(username);
// authorizationPolicy.setPassword(password);
// authorizationPolicy.setAuthorizationType("Basic");
// http.setAuthorization(authorizationPolicy);
// Authenticator myAuth = new Authenticator()
// {
// @Override
// protected PasswordAuthentication getPasswordAuthentication()
// {
// return new PasswordAuthentication(username, password.toCharArray());
// }
// };
// Authenticator.setDefault(myAuth);
最佳答案
在这里找到了一个可行的解决方案http://techpolesen.blogspot.se/2007/08/using-ssl-with-xfirecxf-battling.html,该解决方案重写了TrustManager以使其接受不存在证书的连接:
String targetAddr = http.getTarget().getAddress().getValue();
if (targetAddr.toLowerCase().startsWith("https:")) {
TrustManager[] simpleTrustManager = new TrustManager[] { new X509TrustManager() {
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
} };
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setTrustManagers(simpleTrustManager);
tlsParams.setDisableCNCheck(true);
http.setTlsClientParameters(tlsParams);
}