locked
How to Consume or Call a WCF Service With Basic Authentication From Windows Application RRS feed

  • Question

  • User1360833881 posted

    Hi,

    Can someone give me sample code to consume/call a wcf service with Basic Authentication (Need to Pass UserName and Password)
    from windows Forms application.

    Actually when I am trying to add service reference to below WCF Service URL I am getting error as Operation Timed out.
    https://webservice.abc.gov.sa/abcfinance.finance.svc?wsdl

    The instructions written in the document of Service Provider are below.

    This ABC Service can be accessed over HTTPS Certificate using TLS V1.2.

    This ABC service can be accessed through basic authentication over HTTPS.

    Monday, November 4, 2019 6:33 AM

Answers

  • User-330142929 posted

    Hi,

    After we have added the service reference, we should ensure the service endpoint based on HTTPS protocol, like below,

    <system.serviceModel>
    <bindings>
    <basicHttpBinding>
    <binding name="BasicHttpBinding_IService">
    <security mode="Transport">
    <transport clientCredentialType="Basic" />
    </security>
    </binding>
    </basicHttpBinding>
    </bindings>
    <client>
    <endpoint address="https://vabqia969vm:21011/" binding="basicHttpBinding"
    bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
    name="BasicHttpBinding_IService" />
    </client>
    </system.serviceModel>

    Then we call the service by specifying the Basic credential.

    ServiceReference1.ServiceClient client = new ServiceClient();
    //Basic credentials. client.ClientCredentials.UserName.UserName = "administrator"; client.ClientCredentials.UserName.Password = "abcd1234!"; try { var result = client.SayHello(); Console.WriteLine(result); } catch (Exception) { throw; }

    By default, the credential is the windows account on the server-side, we could change the validation mode by means of the below statements.

    sh.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
    sh.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustUserNamePasswordVal();

    The CustUserNamePasswordVal is a custom class implemented the UserNamePasswordValidator abstract class.
    One more thing we should pay attention to is that we have to trust the certificate on the server-side, which is used to secure the communication, so as to establish the connection between the server-side and the client-side. We either install the server certificate in the local CA or add the below statement before the invocation.

    ServicePointManager.ServerCertificateValidationCallback += delegate
    {
    return true;
    };
    ServiceReference1.ServiceClient client = new ServiceClient();

    Feel free to let me know if there is anything I can help with.
    Best Regards
    Abraham

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 5, 2019 7:12 AM

All replies

  • User-330142929 posted

    Hi,

    After we have added the service reference, we should ensure the service endpoint based on HTTPS protocol, like below,

    <system.serviceModel>
    <bindings>
    <basicHttpBinding>
    <binding name="BasicHttpBinding_IService">
    <security mode="Transport">
    <transport clientCredentialType="Basic" />
    </security>
    </binding>
    </basicHttpBinding>
    </bindings>
    <client>
    <endpoint address="https://vabqia969vm:21011/" binding="basicHttpBinding"
    bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
    name="BasicHttpBinding_IService" />
    </client>
    </system.serviceModel>

    Then we call the service by specifying the Basic credential.

    ServiceReference1.ServiceClient client = new ServiceClient();
    //Basic credentials. client.ClientCredentials.UserName.UserName = "administrator"; client.ClientCredentials.UserName.Password = "abcd1234!"; try { var result = client.SayHello(); Console.WriteLine(result); } catch (Exception) { throw; }

    By default, the credential is the windows account on the server-side, we could change the validation mode by means of the below statements.

    sh.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
    sh.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustUserNamePasswordVal();

    The CustUserNamePasswordVal is a custom class implemented the UserNamePasswordValidator abstract class.
    One more thing we should pay attention to is that we have to trust the certificate on the server-side, which is used to secure the communication, so as to establish the connection between the server-side and the client-side. We either install the server certificate in the local CA or add the below statement before the invocation.

    ServicePointManager.ServerCertificateValidationCallback += delegate
    {
    return true;
    };
    ServiceReference1.ServiceClient client = new ServiceClient();

    Feel free to let me know if there is anything I can help with.
    Best Regards
    Abraham

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 5, 2019 7:12 AM
  • User1360833881 posted

    Hi Abraham,

    Thanks for the help. In your response, first point says "After we have added the service reference, we...".  This is where I got stuck, I mean when I try to add service reference, its not discovering the service at all and getting network error.

    Actually before trying to add Service Reference in Visual Studio, can you please tell what will happen normally, if we open WebService Url which has basic authentication (username and pwd) in the browser. I mean will it ask for UserName and Password in pop-up window or something else will happen.

    Coming to the last point about certificate, I didn't understand how it will work. Can you please elaborate or give an simple example or any helpful links would also be fine. Thanks.

    Best Regards

    Ali

    Thursday, November 7, 2019 9:05 AM
  • User-330142929 posted

    Hi,
    If there is an error that occurred during adding the service reference, the service might run improperly. Actually, I also cannot access the WSDL (service metadata).
    Generally, the WCF service with Basic authentication doesn’t indicate that it can be accessed in the browser. Due to WCF service has two styles to publish the service, one is SOAP web service, the other is Rest API, which could be called in the browser directly. In that case, it will prompt the user to input the username/password when accessing the service in the browser. but SOAP service cannot. the client credential must be provided when calling the service by a client proxy.
    The last topic relates to validating the server certificate on the client-side. it seems a little too early to discuss this issue now.
    https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/working-with-certificates
    In summary, please first resolve the error of not discovering the service since no matter what type of service is(SOAP/Rest), it should be able to add a service reference.
    Feel free to let me know if there is anything I can help with.
    Best Regards
    Abraham

    Monday, November 11, 2019 8:00 AM
  • User1360833881 posted

    Hi Abraha Qian,

    You are absolutely right, there was problem with the service earlier, so now when I added the service reference, its added successfully and entry is made in my web.config, but binding is webHttpBinding not basic. But I am facing issue while calling to that service, it accepts multiple parameters, while I can able to prepare the parameters in object class, I need help on how to pass them to the service. Thanks in advance.

    Wednesday, November 20, 2019 2:26 PM
  • User-330142929 posted

    Hi,
    Basichttpbinding has nothing with Basic authentication.
    Are you sure that the binding in the client configuration file is WebHttpBinding? as far as I know, the WCF service created by Webhttpbinding is called Rest style service and by default doesn’t support generating the service endpoint when we add the service reference.
    If the service is Rest style. It is enough to call the service by constructing an Http request and set the basic credential. we needn't use a client proxy, like above.

    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri("https://vabqia969vm:21011/getresult");
    var bytearray = Encoding.ASCII.GetBytes("administrator:abcd1234!");
    var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(bytearray));
    client.DefaultRequestHeaders.Authorization = header;
    HttpResponseMessage response = client.GetAsync("").Result;
    HttpContent content = response.Content;
    var result = content.ReadAsStringAsync();


    Feel free to let me know if there is anything I can help with.
    Best Regards
    Abraham

    Thursday, November 21, 2019 9:13 AM
  • User1360833881 posted

    Dear Abraham,

    I am sorry, binding is wsHttpBinding, and they also mentioned in first point, in their document  as "All the Webservices will be using SOAP".

    But I have one question, in your previous post you said, if the service is SOAP, we can't access in browser, but we can able to access this service by browser from our IP Address(should be valid one) and it is asking for credentials in the pop up and displaying all the methods (wsdl info). Just wanted to clarify here as well.

    After resolving some 5-6 issues, I can able to call the service, but getting exception/response as 

    "There was no endpoint listening at https://webservice.redf.gov.sa/RedfFinance.Finance.svc/RedfFinance that could accept the message.
    This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details."

    Inner Exception Message: "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 212.12.180.147:443"

    I got struck from the last few hours. Kindly help. Thanks.

    Thursday, November 21, 2019 11:16 AM
  • User-330142929 posted

    Hi,

    After resolving some 5-6 issues, I can able to call the service, but getting exception/response as 

    Given that I have missed so many contents, I suggest you post a new thread and describe the issue in detail. How did you call the service properly? how did the error happen?
    About consuming the WCF service,

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client

    Best Regards
    Abraham

    Monday, November 25, 2019 8:28 AM
  • User1360833881 posted

    Dear Abraham,

    Sure I will create a new post for the error which I am facing currently.

    Kindly just answer me only one question, in the previous post you said that

    "Generally, the WCF service with Basic authentication doesn’t indicate that it can be accessed in the browser. Due to WCF service has two styles to publish the service, one is SOAP web service, the other is Rest API, which could be called in the browser directly. In that case, it will prompt the user to input the username/password when accessing the service in the browser. but SOAP service cannot"

    And in the another post it is mentioned about binding that

    "as far as I know, the WCF service created by Webhttpbinding is called Rest style service and by default doesn’t support generating the service endpoint when we add the service reference.If the service is Rest style. It is enough to call the service by constructing an Http request and set the basic credential. we needn't use a client proxy"

    My question is, when I added service reference in my web application (client), wsHttpBinding is added in web.config file, so it means it is SAOP service (it is also mentioned in their document that it is SOAP), but how it is getting accessed by browser also when it is not REST. Hope you understand.

    Monday, November 25, 2019 8:53 AM
  • User-330142929 posted

    Hi,

    Sorry for my statement is ambiguous. Yes, the service metadata(start page and WSDL, SingleWSDL page) could be accessed in-browser, the method of the service just can not be invocated in the browser directly.  while the Rest API could be routed by URL fragment in the browser, thereby the Http-Get Operation could be called directly in a browser.

    [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            [WebGet]
            string GetData(int value);

    Best Regards

    Abraham

    Tuesday, November 26, 2019 2:47 AM