Java 如何使用用户名/密码(无证书)通过https设置CXF/SOAP客户端连接
我们有一个SOAP Web服务,我们正试图通过https连接设置和用户名/密码连接来获取连接,不应涉及任何证书。Java似乎仍在尝试证书握手,但失败了。如何设置连接,使其能够使用用户名/密码 在MyWeb上尝试查询调用时生成错误:Java 如何使用用户名/密码(无证书)通过https设置CXF/SOAP客户端连接,java,soap,cxf,password-protection,Java,Soap,Cxf,Password Protection,我们有一个SOAP Web服务,我们正试图通过https连接设置和用户名/密码连接来获取连接,不应涉及任何证书。Java似乎仍在尝试证书握手,但失败了。如何设置连接,使其能够使用用户名/密码 在MyWeb上尝试查询调用时生成错误: 2012-08-29 13:31:19,918 WARN (LogUtils.java:371) - Interceptor for {http://myaddress/}MyWebService#{http://myqname/}getStatus has thr
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>
在此处找到一个工作解决方案,该解决方案覆盖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);
}
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);
}