title: How do I pass username/password credentials from php client to self-hosted wcf service?
body: <p>I have a self-hosted wcf service that just adds 2 numbers and returns the value.  It works fine, but I am not sure how I can send the username and password through the php client, so it will validate against my CustomUserNamePasswordValidator.  Here is the implementation for the Add Method:</p>
  
  <pre><code>public class MathService : IMathService
  {
      public double Add(double x, double y)
      {
          return x + y;
      } 
  }
  </code></pre>
  
  <p>Here is my current App.Config:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;configuration&gt;
  &lt;system.serviceModel&gt;
  &lt;services&gt;
    &lt;service behaviorConfiguration="MyServiceBehavior" name="WcfWithPhp.MathService"&gt;
      &lt;endpoint address="" binding="basicHttpBinding" contract="WcfWithPhp.IMathService"&gt;
        &lt;identity&gt;
          &lt;dns value="localhost" /&gt;
        &lt;/identity&gt;
      &lt;/endpoint&gt;
      &lt;endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /&gt;
      &lt;host&gt;
        &lt;baseAddresses&gt;
          &lt;add baseAddress="http://localhost:8731/MathService" /&gt;
        &lt;/baseAddresses&gt;
      &lt;/host&gt;
    &lt;/service&gt;
  &lt;/services&gt;
  &lt;behaviors&gt;
    &lt;serviceBehaviors&gt;
      &lt;behavior name="MyServiceBehavior"&gt;
        &lt;serviceMetadata httpGetEnabled="True"/&gt;
        &lt;serviceDebug includeExceptionDetailInFaults="False" /&gt;
      &lt;/behavior&gt;
    &lt;/serviceBehaviors&gt;
  &lt;/behaviors&gt;
  &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>I am starting the service like this:</p>
  
  <pre><code>static void Main(string[] args)
  {
      ServiceHost host = new ServiceHost(typeof(WcfWithPhp.MathService));
      host.Open();
  
      Console.WriteLine("Math Service Host");
      Console.WriteLine("Service Started!");
  
      foreach (Uri address in host.BaseAddresses)
      {
          Console.WriteLine("Listening on " + address);
      }
  
      Console.WriteLine("Press any key to close the host...");
      Console.ReadLine();
      host.Close();
  }
  </code></pre>
  
  <p>For the php client, I am doing:</p>
  
  <pre><code>&lt;?php
  
  header('Content-Type: text/plain');
  
  echo "WCF Test\r\n\r\n";
  
  // Create a new soap client based on the service's metadata (WSDL)
  $client = new SoapClient("http://localhost:8731/MathService?wsdl");
  
  $obj-&gt;x = 2.5;
  $obj-&gt;y = 3.5;
  
  $retval = $client-&gt;Add($obj);
  
  echo "2.5 + 3.5 = " . $retval-&gt;AddResult;
  
  ?&gt;
  </code></pre>
  
  <p>The above works fine without authentication, but I want to be able to authenticate the username and password from the phpclient.  When they try to access my service, I want the username and password to validate through the overriden Validate method of the UserNamePasswordValidator, which is currently defined as:</p>
  
  <pre><code>public override void Validate(string userName, string password)
  {
          if (string.IsNullOrEmpty(userName))
              throw new ArgumentNullException("userName");
          if (string.IsNullOrEmpty(password))
              throw new ArgumentNullException("password");
  
          // check if the user is not test
          if (userName != "test" || password != "test")
              throw new FaultException("Username and Password Failed");
   }
  </code></pre>
  
  <p>I am just using test and test as an example for the username and password.  I know I have to set the modify the behavior configuration and do a binding configuration, so the service will use the CustomUserNamePasswordValidator, but since I don't know PHP, I am not sure how to send the credentials from php to the wcf service and once the credentials are sent, I don't know how to set it in the wcf service.  I am not creating a wcf service.  I thought I could do <code>client.ClientCredentials.UserName.UserName</code> and <code>client.ClientCredentials.UserName.Password</code>, but this is only if I am creating .NET client which I am not.</p>
  
  <p>Another question I had was that if the client is a php client, am I restricted to only basicHttpBinding?</p>
  
  <p>Also,  ideally what I would like to do is send a soap request from the php client to the wcf service, so if anyone can point me in the right direction for this, it would be great.</p>
  
  <p>I just tried the following, but it didn't work (Add was called, but it wasn't authenticated)</p>
  
  <pre><code>$sh_param = array('userName' =&gt; 'test', 'passWord' =&gt; 'test2');
  
  $headers = new SoapHeader('http://localhost:8731/MathService.svc','UserCredentials',   
  $sh_param,false);
  
  $client-&gt;__setSoapHeaders(array($headers));
  </code></pre>
  
  <p>UPDATE:
  My PHP Soap Client initialization is now:</p>
  
  <pre><code>$client = new SoapClient('http://localhost:8731/MathService?wsdl',
                           array('login' =&gt; "test2", 
                                 'password' =&gt; "test",
                                 'trace'=&gt;1));
  </code></pre>
  
  <p>By doing the above, it added the following in the Request:</p>
  
  <pre><code>`Authorization: Basic dGVzdDI6dGVzdA==`
  </code></pre>
  
  <p>However, my wcf service which is hosted in a console app, is not picking up this authorization, I have a custom username validator which has a hard-coded value of test for the username and test for the password, but when I try "test2" for the login, it is still calling the method.  I am using TransportWithCredentialOnly and Message="UserName"</p>