Friday, October 15, 2010

WCF client to Java web service

I was trying to connect a Java – JBoss Web service over HTTPS from a WCf client. I just rolled my sleeves and opened a C# project and added a service reference to the web service.

Hit F5 and was hoping it would work, I wouldn't blog about it if it worked, would I :) ?

I had to solve series of problems to get this thing working.

Problem #1. The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm="EJBServiceEndpointServlet Realm"'.

After looking at the exception, and Fiddler-ing I found out that I had to change Authentication schema to ‘Basic’ rather than ‘Anonymous’ in the custom binding VS generated.

Problem #2. The remote server returned an unexpected response: (505) HTTP Version Not Supported.

This where things got trickier, It was making two HTTPS calls to the server, First call with “Expect: 100-continue” SOAP header and it has no Authorization header, Server responds back with HTTP/1.1 401 Unauthorized. Then client makes the second call with Authorization but this time server returns a strange message, HTTP/1.1 505 HTTP Version Not Supported.

First Call

POST https://*********** HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:queueMessage"
Host: ***********
Content-Length: 1188
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

Second Call

POST https://*********** HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:queueMessage"
Accept-Encoding: gzip, deflate,gzip, deflate
Authorization: Basic **************
Host: *********
Content-Length: 1188
Expect: 100-continue

Even after banging my head on Google results for a long time, I ended up asking web service developer to send me a copy of his working Java client, hoping to diff the SOAP header to get some clues.

I got the Java source code with a little .bat file to execute the java program. I turned Fiddler on and ran the Java client, Oops! nothing on Fiddler. After some more googling, found out another fact, Java client is not detecting proxy[ in my case Fiddler].  Some more googling lead to this link,

http://www.fiddler2.com/fiddler/help/hookup.asp

Configure a Java application to use Fiddler.
Per http://www.davidreilly.com/java/java_network_programming/#2.4 you should be able to do something like:

jre -DproxySet=true -DproxyHost=127.0.0.1 -DproxyPort=8888 MyApp

As the link suggested, added proxy settings parameters and ran the program again. This time its a different error PKIX path building failed with long stack trace.

Some more googling, I landed here http://code.google.com/apis/gdata/articles/wireshark.html

At this point I didn't have any other choice than to modify Java code, downloaded Netbeans IDE, I like it better than Eclipse, I wandered some more time in the new IDE, to add a new Java class file in the project.After successfully compiling the source code, I was able to see the HTTPS traffic in Fiddler.

Now I am back to my original problem. HTTP/1.1 505 HTTP Version Not Supported. After comparing the SOAP messages generated by Java and WCF client, and some googling, I landed here http://connect.microsoft.com/VisualStudio/feedback/details/368230/incorrect-http-1-1-expect-100-continue-behaviorSo the rogue line is Expect: 100-continue SOAP header, Seems like JBoss has some issues with handling

Expect: 100-continue header.

I added this magic line as suggested in the issue, voila, Everything worked and everybody was happy.

8 Comments :

Anonymous said...

thanks for this tips

Ola said...

Thanks, thanks, thanks...

ValiantThor said...

Top work. I had the same with Apache TOMCAT Web Service over SSL.

Marcelo Finki said...

Hello.
When you said: "...change Authentication schema to ‘Basic’ rather than ‘Anonymous’ in the custom binding VS generated..."

Could you please show the exact XML source code of your

i would appreciate some clarification:
Should i change from:

to:


Thanks in advance.
Marcelo

Marcelo Finki said...

Hello.
When you said: "...change Authentication schema to ‘Basic’ rather than ‘Anonymous’ in the custom binding VS generated..."

Could you please show the exact XML source code of your <system.serviceModel/>

i would appreciate some clarification:
Should i change from:
<transport clientCredentialType="None"/>
to:
<transport clientCredentialType="Basic"/>

Thanks in advance.
Marcelo
Thanks in advance.
Marcelo

இரா.செந்தில் said...

@Marcelo Finki I am sorry, I dont have the source file with me. Argh!!!. But it feels like, clientCredentialType is the one you want to change. Let me know if it doesn't work, I can try to find the source.

Marcelo Finki said...

Just in case this helps:

My case: I use a client certificate to authenticate.

I got it work using this configuration:
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>

Cheers!
Marcelo Finkielsztein


Valdis Iljuconoks said...

Old post but useful :)