9
votes

I'm developing an application where i have to consume webservice developed in Java using http protocol. I'm developing the application using C#.NET winforms. Everything works fine until now. The webservice is now using SSL security hence the service protocol changed from http to https. I'm facing issues while accessing the https webservice.

I tried accessing the https webservice from the SoapUI by providing the Authenticaion Parameters (UserName and Password) from the Auth tab as shown below:

enter image description here

It is working fine from SoapUI.

but wen i provide the Authenticaion parameters from code as below its not working:

client.ClientCredentials.UserName.UserName = "admin";
client.ClientCredentials.UserName.Password = "*******";

I'm using Security Mode as : TransportWithMessageCredential and ClientCredentialTtype as : Basic

My App.Config file is as below:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <system.serviceModel>
    <client>
      <endpoint address="https://xyz:8001/HelloWorldAPI/HelloWorldWebService"
       binding="wsHttpBinding"
        bindingConfiguration="myhttpsbinding" contract="API.HelloWorldWebService"
        name="HelloWorldWebServicePort" />
    </client>
    <bindings>
      <wsHttpBinding>
        <binding name="myhttpsbinding">
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="Basic"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>
  <system.net>
    <defaultProxy useDefaultCredentials="true" />
  </system.net>
</configuration>

My Code as below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using testingtool.API;

namespace testingtool
{
    class Program
    {
        static void Main(string[] args)
        {
            new APITool();
        }
    }
    class APITool
    {
        UserInfo userinfo = new UserInfo();
        HelloWorldWebServiceClient client = new HelloWorldWebServiceClient();

        private bool ValidationCallBack(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)
        {
            return true;
        }

        public APITool()
        {
            try
            {
                //Authentication parameters
                client.ClientCredentials.UserName.UserName = "admin";
                client.ClientCredentials.UserName.Password = "*****";
                ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidationCallBack);

                //client ClientCredentials @ Application level
                userinfo.userid = "myusername";
                userinfo.password = "*****";
                GetHelloWorldAPIVersionRequest request = new GetHelloWorldAPIVersionRequest();

                APIVersionInfo versioninfo = new APIVersionInfo();
                versioninfo.userinfo = userinfo;
                request.APIVersionInfo = versioninfo;


                APIVersionInfoResponse response = client.GetHelloWorldAPIVersion(versioninfo);
                Console.WriteLine(response.Version);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            Console.ReadLine();
        }
     }
  } 

I'm getting following exception:

System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm="EJBServiceEndpointServlet Realm"'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.

EDIT: from the client i have verified with Fiddler the request window as below: from the AUth tab it is saying that there is no Autherization Header present.

enter image description here

Fiddler Raw Request as below:

CONNECT 10.10.10.110:8001 
HTTP/1.1 Host: 10.10.10.110:8001 
Connection: Keep-Alive 
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

Any help wouldbe greatly appreciated.

6
Can you confirm on the server that the request is coming in as HTTPS? Maybe using Fiddler, you can extract the actual message sent. - Patrick Hofman
Thanks for your response,from client end i tried with fiddler , i'm getting 401 error.please see my edited post. - Sudhakar Tillapudi
So if I understand correctly we got clear this is a client problem? That rules out the server side. - Patrick Hofman
@PatrickHofman: Okay, Thanks,so now could you please guide me in solving this issue. - Sudhakar Tillapudi
Since you could access the service from SOAPUI can you compare the raw request from SOAPUI with that from your client application using Fiddler - Rajesh

6 Answers

3
votes

Wondering if the issue could be with the binding, although hard to say for sure without reviewing the service configuration or seeing the successful soapUI request. (Note: you may want to include a snippet of the message, including the soap header, from the soapUI HTTP Log.)

In any case, you may want to make sure the service is really using ws-security (message level security) by trying the following binding:

<bindings>
  <basicHttpBinding>
    <binding name="httpBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
1
votes

You should change your app config:

    <wsHttpBinding>
        <binding name="myhttpsbinding">
          <security mode="TransportWithMessageCredential">
             <transport clientCredentialType="None" />
             <message clientCredentialType="UserName" establishSecurityContext="false" negotiateServiceCredential="false"/>
          </security>
        </binding>
     </wsHttpBinding>

On transport level you have no authentication, so <transport clientCredentialType="None" /> and on message level you have username|password authentication, so <message clientCredentialType="UserName"

0
votes

are you going thru a proxy server? If yes, are the details entered into IE ? Are you able to browse https pages in IE? If yes, this should be picked up by each WebRequest that makes an https call as it needs to issue a CONNECT to the proxy server (which its doing) but in your call the Proxy-Authorization header is missing. This should be your focus - try a plain WebRequest to say https:// google.com and see what you get in fiddler.

You may have an issue with your proxy server forwarding on your request. Are you able to try https on a different network not behind a proxy?

0
votes

Maybe this link can help.

It explains how to configure your endpoint in case of REST/SOAP WebServices

Can not call web service with basic authentication using WCF

0
votes

I have given <security mode="Transport" /> inside binding and issue solved for calling HTTPS service. Full code:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>       
        <binding name="ServiceSoap">
            <security mode="Transport" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>      
      <endpoint address="https://yourlink/Service.asmx" binding="basicHttpBinding" bindingConfiguration="ServiceSoap" contract="EmployeeService.ServiceSoap" name="ServiceSoap"/>
    </client>
  </system.serviceModel>
-1
votes

Its binding issue you need to use custom binding here is example.

http://webservices20.blogspot.com/