Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connect with WCF to a WebService authenticated with username/password

I created a proxy of a Web Service with Visual Studio 2008, and it created for me the following entry in the app.config:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="MyNameHandlerSoapBinding" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://www.***/***/***"
              binding="basicHttpBinding" bindingConfiguration="MyNameHandlerSoapBinding"
              contract="***.MyNameHandler" name="MyName">
          </endpoint>
        </client>
    </system.serviceModel>

The webservice is has username/password authentication so I need to add it somewhere here.

I'm a bit lost in the sea of WCF documentation, I think I have to change from basicHttpBinding to wsHttpBinding or customBinding to be able to add the authentication elements, but I don't really understand it. Could anybody give any quick tip or any useful link that says how to do so?

EDIT:

I changed the security section to:

<security mode="Transport">
    <transport clientCredentialType="Basic" proxyCredentialType="None"
         realm="" />
</security>

and added in the code:

ws.ClientCredentials.UserName.UserName = "";
ws.ClientCredentials.UserName.Password = "";

Now it seems it might be using the credentials but it's giving me the error:

the provided URI scheme 'http' is invalid URI expected 'https'

I don't even know if this is the right way to go...

like image 555
antonioh Avatar asked Apr 30 '09 09:04

antonioh


People also ask

How can I pass a username password in the header to a soap WCF service?

UserName. Password = "testPass"; In this way you can pass username, password in the header to a SOAP WCF Service.

How do I authenticate a user login?

Using HTTP Basic Authentication A client requests access to a protected resource. The Web server returns a dialog box that requests the user name and password. The client submits the user name and password to the server. The server validates the credentials and, if successful, returns the requested resource.

What is TransportWithMessageCredential?

TransportWithMessageCredential is a combination of both transport and message security since transport security encrypts and signs the messages as well as authenticates the service to the client and message security is used to authenticate the client to the service. Follow this answer to receive notifications.


1 Answers

I post here the solution for future readers:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="MyHandlerSoapBinding" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic"  />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://www.***/***/***/MyHandler"
          binding="basicHttpBinding" bindingConfiguration="MyHandlerSoapBinding"
          contract="***.MyHandler" name="MyHandler">
      </endpoint>

    </client>
  </system.serviceModel>

In the end I could use the default basicHttpBinding. The only difference from the code posted in the question is the security node.

Also note the mode="TransportCredentialOnly" option, this allows you to send username/password using http instead of https. This is necessary for testing environments as the one I'm using. Later on obviously you'll prefer https to send your credentials.

Afterwards in code you'll enter your username/password:

var ws = new ***.MyHandlerClient("MyHandler");
ws.ClientCredentials.UserName.UserName = "myUsername";
ws.ClientCredentials.UserName.Password = "myPassword";
var result = ws.executeMyMethod();
like image 59
antonioh Avatar answered Sep 26 '22 02:09

antonioh