views:

2766

answers:

2

I've been given a web service written in Java that I'm not able to make any changes to. It requires the user authenticate with basic authentication to access any of the methods. The suggested way to interact with this service in .NET is by using Visual Studio 2005 with WSE 3.0 installed.

This is an issue, since the project is already using Visual Studio 2008 (targeting .NET 2.0). I could do it in VS2005, however I do not want to tie the project to VS2005 or do it by creating an assembly in VS2005 and including that in the VS2008 solution (which basically ties the project to 2005 anyway for any future changes to the assembly). I think that either of these options would make things complicated for new developers by forcing them to install WSE 3.0 and keep the project from being able to use 2008 and features in .NET 3.5 in the future... ie, I truly believe using WCF is the way to go.

I've been looking into using WCF for this, however I'm unsure how to get the WCF service to understand that it needs to send the authentication headers along with each request. I'm getting 401 errors when I attempt to do anything with the web service.

This is what my code looks like:

WebHttpBinding webBinding = new WebHttpBinding();
        ChannelFactory<MyService> factory = new ChannelFactory<MyService>(webBinding,
                                                                            new EndpointAddress(
                                                                                "http://127.0.0.1:80/Service/Service/"));
        factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
        factory.Credentials.UserName.UserName = "username";
        factory.Credentials.UserName.Password = "password";
        MyService proxy = factory.CreateChannel();
        proxy.postSubmission(_postSubmission);

This will run and throw the following exception:

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

And this has an inner exception of:

"The remote server returned an error: (401) Unauthorized."

Any thoughts about what might be causing this issue would be greatly appreciated.

+4  A: 

First question: is this a SOAP or a REST based Java service you're trying to call?

Right now, with the "webHttpBinding", you're using a REST-based approach. If the Java service is a SOAP service, then you'd need to change your binding to be "basicHttpBinding" instead.

IF it's a SOAP based service, you should try this:

BasicHttpBinding binding = new BasicHttpBinding();

binding.SendTimeout = TimeSpan.FromSeconds(25);

binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = 
                              HttpClientCredentialType.Basic;

EndpointAddress address = new EndpointAddress(your-url-here);

ChannelFactory<MyService> factory = 
             new ChannelFactory<MyService>(binding, address);

MyService proxy = factory.CreateChannel();

proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "password";

I've used this with various web services and it works - most of the time.

If that doesn't work, you'll have to find out more about what that Java webservice expects and how to send that relevant info to it.

Marc

marc_s
A: 

I will add to this as well based on a similar problem I just experienced. I auto-generated the config / proxy with VS -- but the config it created didn't actually work.

Although it had security mode="Transport" set correctly, it didn't have clientCredentialType="Basic" set. I added to that my config and it still didn't work. Then I actually removed the message security that the tool created since the service I'm contacting is SSL + Basic only:

<message clientCredentialType="UserName" algorithmSuite="Default" />

Voila -- it worked.

I'm not sure why this had an effect considering the element did not specify message level security... but it did.

Ethan J. Brown