jQuery in Action, 2nd edition*
The moose likes Web Services and the fly likes How to create web service client to remote SSL service (HTTPS)? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Web Services
Bookmark "How to create web service client to remote SSL service (HTTPS)?" Watch "How to create web service client to remote SSL service (HTTPS)?" New topic
Author

How to create web service client to remote SSL service (HTTPS)?

Sky Loi
Ranch Hand

Joined: Oct 06, 2008
Posts: 65
Hi, all gurus,

I am going to create a web service client connecting to remote HTTPS service. So far, I only have the WSDL file and know the following information about the service authentication:
1. it will generate session id after invoke login command, e.g. https://remote-service-url/services/login?user=abc&password=abc
2. put the return session id in every web service request to make transactions

I have use wsdl2java tool (Apache-CXF) to generate the client stuffs and try to call the remote service. But I keep getting the SSL handshake exception as the following details. I have the following questions:
1. I have not setup any key/certification store in the client side. Should I have to setup them? If yes, how to get the remote certification for client setup?
2. I try to use httpclient or browser to connect to HTTPS service and it works without any certification setting?
3. Is the handshake issue related with lack of session id? But I think they are in different layers.

I have few knowledge in the ws security so it will be appreciate if you could give me some advice.

The detail exception:
....
trigger seeding of SecureRandom
done seeding SecureRandom
trigger seeding of SecureRandom
done seeding SecureRandom
Dec 17, 2009 8:13:39 PM org.apache.cxf.transport.https.SSLUtils getCiphersuites
INFO: The cipher suites have not been configured, falling back to cipher suite filters.
Dec 17, 2009 8:13:39 PM org.apache.cxf.transport.https.SSLUtils getCiphersFromList
INFO: The cipher suites have been set to SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_RSA_WITH_NULL_MD5, SSL_RSA_WITH_NULL_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_DH_anon_WITH_AES_128_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5.
main, setSoTimeout(60000) called
%% No cached client session
*** ClientHello, SSLv3
RandomCookie: GMT: 1261109619 bytes = { 26, 101, 33, 182, 174, 194, 112, 68, 237, 37, 56, 148, 93, 173, 110, 133, 0, 128, 6, 66, 117, 97, 119, 191, 184, 103, 73, 42 }
Session ID: {}
Cipher Suites: [SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_RSA_WITH_NULL_MD5, SSL_RSA_WITH_NULL_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_DH_anon_WITH_AES_128_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
Compression Methods: { 0 }
***
main, WRITE: SSLv3 Handshake, length = 85
main, WRITE: SSLv2 client hello message, length = 110
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
main, SEND TLSv1 ALERT: fatal, description = handshake_failure
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, called close()
main, called closeInternal(true)
Dec 17, 2009 8:13:39 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept
WARNING: Interceptor 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:236)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:472)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:302)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:254)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:123)
at $Proxy53.accountUpdate(Unknown Source)
at com.active.test.TestCRMwithContext.testWSDLClient(TestCRMwithContext.java:500)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:198)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:274)
at org.springframework.test.context.junit4.SpringMethodRoadie$2.run(SpringMethodRoadie.java:207)
at org.springframework.test.context.junit4.SpringMethodRoadie.runBeforesThenTestThenAfters(SpringMethodRoadie.java:254)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:234)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:204)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:146)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:151)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1916)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1871)
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:1934)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:66)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:632)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 31 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
... 47 more
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Hi!
You can find detailed instructions on how to create a web service client using either SSL or Mutual Authentication in a document I have written, which you can download here: http://faq.javaranch.com/content/Exam-Objectives-5.pdf
You will be interested in section 8.3 (page 235-).
The example is using standard Java SE to develop a client, not Apache CXF, but I assume the principle is the same.
Best wishes!
Sky Loi
Ranch Hand

Joined: Oct 06, 2008
Posts: 65
Thanks, Ivan. Your document is very helpful.

I did not figure out some item yet:
1. does the remote secure service need special cert authentication? Looks like I could query the service URL in the browser or pure HTTPClient connection.
2. not sure if any WS implementation compatible issue?

I tried the following actions:
1. setup the web service client with SSL setting but without cert in client side, connecting to https service. It got the handshake exception above.

2. I try to remove the special SSL setting and connecting to https service. The handshake is good and seems the SOAP message is sent out. However, it got the javax.xml.ws.soap.SOAPFaultException: Server. The exception "Server" is too short. I cannot figure out what is the root cause.

3. I try to capture the out/in SOAP message in some tools. Seems I could got the good message in client out SOAP message but the response message server sent back is encrypted. How could I capture all the messages.

Thank you again
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Hi!
Sky Loi wrote:
1. does the remote secure service need special cert authentication? Looks like I could query the service URL in the browser or pure HTTPClient connection.

If you use plain SSL, without mutual authentication, you will indeed be able to "connect" from a browser. Also note that the service developed in my document is set up to require encryption of POST messages only! You do not want to encrypt GET messages, otherwise tools like wsimport will have problems retrieving the WSDL.
2. not sure if any WS implementation compatible issue?

Do you mean between different Java WS frameworks or do you also include other platforms, such as .NET?
HTTPS is transport level encryption, something that should be transparent to the underlying WS framework. Thus, if the different frameworks are compatible without encryption, they should also be compatible with encryption.

Server. The exception "Server" is too short. I cannot figure out what is the root cause.

This means there was an error processing the request in the web service server. You should examine the server's log to learn more about the cause of the error.

3. I try to capture the out/in SOAP message in some tools. Seems I could got the good message in client out SOAP message but the response message server sent back is encrypted. How could I capture all the messages.

You can't, if they are encrypted.
Well, you could simulate a "man in the middle attack", in order to be able to read the content of the encrypted messages, but it seems like a lot of hassle to me.
I would make sure that the web service works correctly, before adding encryption.
Best wishes!
Sky Loi
Ranch Hand

Joined: Oct 06, 2008
Posts: 65
Thank you very much, Ivan. Your information helps me a lot.

My current situation make me headache: I have no access to the remote service server. This is my biggest obstacle to debug my client connection. And I have no idea if the remote service need special cert authentication. Do you know if there is some good debug tools in client side could help me in this situation? Or I could add some interceptors codes in my client side to capture the response SOAP message from server?


Regards
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Hi!
Yes, you are right - you can add a handler on the client side that can, for instance, log SOAP messages from the server.
Note that this requires that the SOAP message really arrives to the client, otherwise the handler will not see it.
It would be very interesting to hear how you solve this problem - I must admit that it sounds like a quite difficult one.
Best wishes!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to create web service client to remote SSL service (HTTPS)?
 
Similar Threads
CXF 2.2.3 with RAD 7.5 that comes with WebSphere test server 6.1 with Servlet 2.4 spec
SOAP compatibility
Issue faced while calling Web service from standalone client using certificate.
Probleme de lancement de test avec StrutsTestCase
Problem in running apache CXF webservice in weblogic 10 server