title: How to configure WCF service deployed on IIS and remote client to authenticate from remote client PC?
body: <p>I'm a noob; please help me understand this authentication config / bindings stuff that confuses me so much.</p>
  
  <p>I have a C# WCF service deployed on IIS 7 on Win 2008.  My client is a Windows Forms C# app.  My client works just fine when it's running from the same server where the WCF service is running, but when I try to run my client from a remote PC, I get the following exception...</p>
  
  <p>System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. </p>
  
  <p>I've read a few posts about these issues, and know that my problem is because my service and client are configured to use Windows authentication, which I guess is the default when using Visual Studio to create the service, and to add the service reference to the client.  Below is my config before I made any changes, when it was still set to Windows (with irrelevant bits removed)...</p>
  
  <p>Web.Config</p>
  
  <pre><code>&lt;system.web&gt;
      ...
      &lt;authentication mode="Windows"/&gt;
      ...
  
  &lt;system.serviceModel&gt;
      &lt;services&gt;
          &lt;service name="MCLaborServer.LaborService" behaviorConfiguration="MCLaborServer.LaborServiceBehavior"&gt;
              &lt;!-- Service Endpoints --&gt;
              &lt;endpoint address="" binding="wsHttpBinding" contract="MCLaborServer.ILaborService"&gt;
                  &lt;!-- 
            Upon deployment, the following identity element should be removed or replaced to reflect the 
            identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
            automatically.
        --&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;/service&gt;
      &lt;/services&gt;
      &lt;behaviors&gt;
          &lt;serviceBehaviors&gt;
              &lt;behavior name="MCLaborServer.LaborServiceBehavior"&gt;
                  &lt;!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --&gt;
                  &lt;serviceMetadata httpGetEnabled="true"/&gt;
                  &lt;!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information --&gt;
                  &lt;serviceDebug includeExceptionDetailInFaults="false"/&gt;
              &lt;/behavior&gt;
          &lt;/serviceBehaviors&gt;
      &lt;/behaviors&gt;
  &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>And from the App.Config on the client...</p>
  
  <pre><code>&lt;system.serviceModel&gt;
      &lt;bindings&gt;
          &lt;wsHttpBinding&gt;
              &lt;binding name="WSHttpBinding_ILaborService" closeTimeout="00:01:00"
                  openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                  bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                  maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                  messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                  allowCookies="false"&gt;
                  &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                      maxBytesPerRead="4096" maxNameTableCharCount="16384" /&gt;
                  &lt;reliableSession ordered="true" inactivityTimeout="00:10:00"
                      enabled="false" /&gt;
                  &lt;security mode="Message"&gt;
                      &lt;transport clientCredentialType="Windows" proxyCredentialType="None"
                          realm="" /&gt;
                      &lt;message clientCredentialType="Windows" negotiateServiceCredential="true"
                          algorithmSuite="Default" establishSecurityContext="true" /&gt;
                  &lt;/security&gt;
              &lt;/binding&gt;
          &lt;/wsHttpBinding&gt;
      &lt;/bindings&gt;
      &lt;client&gt;
          &lt;endpoint address="http://&lt;myDnsNameGoesHere&gt;/MCLaborServer/LaborService.svc"
              binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ILaborService"
              contract="LaborService.ILaborService" name="WSHttpBinding_ILaborService"&gt;
              &lt;identity&gt;
                  &lt;dns value="localhost" /&gt;
              &lt;/identity&gt;
          &lt;/endpoint&gt;
      &lt;/client&gt;
  &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>So, first I changed "authentication mode="None"" in the web.config, and set "security mode="None"" in the client's app.config, and set both the clientCredentialType="None" for message and transport.  I also commented out the "identity" sections in both the web.config and client's app.config.  That broke it completely though and now the client running locally won't even work; it gives a "The remote server returned an unexpected response: (405) Method Not Allowed" error.</p>
  
  <p>So what can I do to turn security off so that I can connect using a remote client?  I do have anonymous access enabled by the way in IIS for my application.</p>
  
  <p>I'd also like to ask, what's the best practice way to configure this so I can make webservice calls on a remote client over the internet in a semi-secure fashion without using SSL or doing anything that would cost money.  I'm not really that concerned about security of the data because it's not really sensitive data, but still I'd like to make sure the server isn't open to attacks.</p>
  
  <p>Also, I read that I can use Windows authentication, and then explicitly specify credentials in code, like below.  If I do that, will it still work remotely?  And if so, does that end up making my Windows credentials for the server be sent over the wire in an insecure fashion, so then I'd be open to getting my credentials hijacked?</p>
  
  <pre><code>SomeService.ServiceClient someService = new SomeService.ServiceClient(); 
  someService.ClientCredentials.Windows.ClientCredential.UserName="windowsuseraccountname" 
  someService.ClientCredentials.Windows.ClientCredential.Password="windowsuseraccountpassword"
  </code></pre>
  
  <p>I've read through the following posts / links, but still am confused.  Thanks for any help!</p>
  
  <p><a href="https://stackoverflow.com/questions/284538/wcf-error-the-caller-was-not-authenticated-by-the-service">WCF error: The caller was not authenticated by the service</a></p>
  
  <p><a href="https://stackoverflow.com/questions/5209380/how-to-fix-the-caller-was-not-authenticated-by-the-service">How to fix &quot;The caller was not authenticated by the service&quot;?</a></p>
  
  <p><a href="http://msdn.microsoft.com/en-us/library/aa291347(v=vs.71).aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/aa291347(v=vs.71).aspx</a></p>
  
  <p><a href="http://www.devx.com/codemag/Article/33342/1763/page/2" rel="nofollow noreferrer">http://www.devx.com/codemag/Article/33342/1763/page/2</a></p>