Today I had trouble getting
CXF (the new
xfire) to access a WSDL file located on a SSL-based URL. In addition, it was behind basic authentication. Let us jump right in. I got this error:
org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:48)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:206)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:253)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:204)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:179)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:199)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:185)
at com.blogspot.techpolesen.ws.DynamicClient.atSystemHentBilagsnavneForSag(DynamicClient.java:66)
at com.blogspot.techpolesen.ws.DynamicClient.main(DynamicClient.java:25)
Caused by: java.io.IOException: Illegal Protocol https for HTTP URLConnection Factory.
at org.apache.cxf.transport.http.HttpURLConnectionFactoryImpl.createConnection(HttpURLConnectionFactoryImpl.java:44)
at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:468)
at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:46)
... 8 more
Exception in thread "main" org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:48)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:206)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:253)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:204)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:179)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:199)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:185)
at com.blogspot.techpolesen.ws.DynamicClient.atSystemHentBilagsnavneForSag(DynamicClient.java:66)
at com.blogspot.techpolesen.ws.DynamicClient.main(DynamicClient.java:25)
Caused by: java.io.IOException: Illegal Protocol https for HTTP URLConnection Factory.
at org.apache.cxf.transport.http.HttpURLConnectionFactoryImpl.createConnection(HttpURLConnectionFactoryImpl.java:44)
at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:468)
at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:46)
... 8 more
And googling it eventually led me to
the page on configuring SSL support but it does not tell the complete story. What solved my problem was to add a
cxf.xml to the root of my classpath, with this content:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<http:conduit name="{https://myhost.com/this/is/namespace}MyPortName.http-conduit">
<http:authorization>
<sec:UserName>usernamehere</sec:UserName>
<sec:Password>passwordhere</sec:Password>
</http:authorization>
<http:tlsClientParameters secureSocketProtocol="SSL">
</http:tlsClientParameters>
</http:conduit>
</beans>
It was the
secureSocketProtocol="SSL" attribute that solved the problem. Of course, you need to change "
{https://myhost.com/this/is/namespace}MyPortName" into a namespace and port name that matches your WSDL. Also note, that I have added static basic authentication credentials to get access to my wsdl.
12 kommentarer:
I am having the same problem.
I have a simple web service and client. When I host it on Tomcat at http://localhost:8080/service/services, the client connects just fine, but it does not work when using https://localhost:8443/service/services.
I am using spring.
For connection on http://localhost:8080/service/services
here is the relevant portion of the spring config file on the server:
<jaxws:endpoint
id="connectionAdmin"
implementor="#connectionAdminService"
address="/connectionAdminService" />
here is the relevant portion of the spring file for the client:
<bean id="adminClient" class="gov.nwcg.isuite.service.webservice.admin.ConnectionAdminService" factory-bean="adminClientFactory" factory-method="create"/>
<bean id="adminClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="gov.nwcg.isuite.service.webservice.admin.ConnectionAdminService"/>
<property name="address" value="http://localhost:8080/service/services/connectionAdminService"/>
</bean>
The server page at http://localhost:8080/service/services/ returns:
{http://gov.nwcg.isuite.webservice}ConnectionAdmin
When I run the client, it connects to the web service and everything is fine
now I want to connect on https
I change the spring config on the client to have an http:conduit with SSL and change the address of the client factory. It now reads:
<http:conduit name="{https://gov.nwcg.isuite.webservice}ConnectionAdmin.http-conduit">
<http:tlsClientParameters secureSocketProtocol="SSL">
</http:tlsClientParameters>
</http:conduit>
<bean id="adminClient" class="gov.nwcg.isuite.service.webservice.admin.ConnectionAdminService" factory-bean="adminClientFactory" factory-method="create"/>
<bean id="adminClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="gov.nwcg.isuite.service.webservice.admin.ConnectionAdminService"/>
<property name="address" value="https://localhost:8443/service/services/connectionAdminService"/>
</bean>
The server page at https://localhost:8443/service/services/ returns:
{http://gov.nwcg.isuite.webservice}ConnectionAdmin
When the client runs, I get the same error you were getting:
......
Caused by: java.io.IOException: Illegal Protocol https for HTTP URLConnection Factory.
at org.apache.cxf.transport.http.HttpURLConnectionFactoryImpl.createConnection(HttpURLConnectionFactoryImpl.java:44)
at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:468)
at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:46)
... 7 more
Any idea what I am missing?
Hi Douglas,
I have not tried that exact config, but I might have a suggestion. You write that you are configuring a conduit on the client with this name:
"{https://gov.nwcg.isuite.webservice}ConnectionAdmin.http-conduit"
But, you also write that the server, after being deployed on ssl, still have this conduit name:
"{http://gov.nwcg.isuite.webservice}ConnectionAdmin"
Which I think is correct. As far as I understand, the conduit name is put together like this:
"{namespace-of-service}ServiceName"
And the namespace should not change, just because the access protocol changes. It just happens to be, that the namespace defaults to being a URL, which can be confusing.
What happens, when you change the conduit name in you spring config to:
"{http://gov.nwcg.isuite.webservice}ConnectionAdmin"
and access the SSL service?
Thanks for your quick response
I have tried various combinations of the http-conduit but all have failed.
<http:conduit name="{http://gov.nwcg.isuite.webservice}ConnectionAdmin.http-conduit">
</http:conduit>
<http:conduit name="{http://gov.nwcg.isuite.webservice}ConnectionAdmin.http-conduit">
<http:tlsClientParameters>
</http:tlsClientParameters>
</http:conduit>
<http:conduit name="{http://gov.nwcg.isuite.webservice}ConnectionAdmin.http-conduit">
<http:tlsClientParameters>secureSocketProtocol="SSL"
</http:tlsClientParameters>
</http:conduit>
<http:conduit name="{http://gov.nwcg.isuite.webservice}ConnectionAdmin.http-conduit">
<http:tlsClientParameters>secureSocketProtocol="ssl"
</http:tlsClientParameters>
</http:conduit>
I know that the file is being read because if I make some big error (such as an invalid xml ) I get a different error
I am not sure what to try next.
any ideas?
Hi
I have the same problem and still don't know what I'm doing wrong but
as temporary solution you can try (it works for me):
YourService ss = new YourService(wsdlURL, SERVICE_NAME);
YourPort port = ss.getYourPort();
Client c = ClientProxy.getClient(port);
HTTPConduit conduit = (HTTPConduit) c.getConduit();
TLSClientParameters tlsParams = new TLSClientParameters();
conduit.setTlsClientParameters(tlsParams);
Thanks for this post, we are not alone!
Here the workaround I used:
69 Client client = ClientProxy.getClient(port);
70 HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
71 HTTPClientPolicy httpClientPolicy = httpConduit.getClient();
[...]
86 if("https".equalsIgnoreCase(SERVICE_URL.getProtocol())) {
87 TLSClientParameters tlsParams = new TLSClientParameters();
88 tlsParams.setSecureSocketProtocol("SSL"); // TODO do we need it?
89 httpConduit.setTlsClientParameters(tlsParams);
90 }
Filippo
I also was unable to get http:conduit to work.
I'm using a ClientProxyFactoryBean with the simple service. Here's the code that worked:
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setServiceClass(WidgetServiceRead.class);
factory.setAddress(url);
m_svc = (WidgetServiceRead) factory.create();
if (url.toLowerCase().startsWith("https:")) {
Client client = ClientProxy.getClient(m_svc);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
httpConduit.setTlsClientParameters(tlsParams);
}
I too have struggled to get the Spring configured client (using JaxWsProxyFactoryBean) working with the http:conduit SSL configuration.
While this is not ideal, it seems to work:
<http:conduit name="*.http-conduit">
...
</http>
I love these posts when people help each other out with code, on many an evening I wish I had help with some of the programs I have written. keep up the good work.
I've been struggling for many hours with this http:conduit problem and I've found a solution.
For me CXF expected something which event wasn't in wsdl file. I had to debug CXF code to find it and I'd recommend doing the same. Just put the breakpoint in ConfigurerImpl.configureWithWildCard() method and check value of first param. This is the value you should enter as http:conduit id.
Hope that helps,
Pawel
Pawel your a star,
Your approach solved my problem !
Cheers,
Paul
Thanks guys, this is a great post.
My scenario is to be able to connect to the https service regardless of the actual server certificate. Basically I want to "trust" the server, no matter what. So I choose to set a dummy TrustManager into the HTTPConduit. Here's the code to do it:
private void configHttpConduit(Object service) {
Client clientProxy = ClientProxy.getClient(service);
HTTPConduit conduit = (HTTPConduit) clientProxy.getConduit();
String targetAddr = conduit.getTarget().getAddress().getValue();
if (targetAddr.toLowerCase().startsWith("https:")) {
TrustManager[] simpleTrustManager = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
} };
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setTrustManagers(simpleTrustManager);
tlsParams.setDisableCNCheck(true);
conduit.setTlsClientParameters(tlsParams);
}
}
Cheers,
GZ
Thanks guys, this is a great post.
My scenario is to be able to connect to the https service regardless of the actual server certificate. Basically I want to "trust" the server, no matter what. So I choose to set a dummy TrustManager into the HTTPConduit. Here's the code to do it:
private void configHttpConduit(Object service) {
Client clientProxy = ClientProxy.getClient(service);
HTTPConduit conduit = (HTTPConduit) clientProxy.getConduit();
String targetAddr = conduit.getTarget().getAddress().getValue();
if (targetAddr.toLowerCase().startsWith("https:")) {
TrustManager[] simpleTrustManager = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
} };
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setTrustManagers(simpleTrustManager);
tlsParams.setDisableCNCheck(true);
conduit.setTlsClientParameters(tlsParams);
}
}
Cheers,
GZ
Post a Comment