Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The server has rejected the client credentials, WCF as Windows Service

I am able to connect to my WCF service with the Win-form application, however i am not able to do so with my windows service. Whenever i fire open() to the proxy it throws the following error

The server has rejected the client credentials

Inner Exception: System.Security.Authentication.InvalidCredentialException: The server has rejected the client credentials.
---> System.ComponentModel.Win32Exception: The logon attempt failed
--- End of inner exception stack trace ---
at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, ChannelBinding binding, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
at System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)

Tried searching for the solution, but none fitting my requirements, hence posted.

Please help...

Update 1:

@A.R., Tried using

client.ClientCredentials.Windows.AllowedImpersonationLevel =
    System.Security.Principal.TokenImpersonationLevel.Impersonation;

but to no avail.

Update 2:

WCF service Configuration

<system.serviceModel>
    <diagnostics performanceCounters="All" />
    <bindings>
      <netTcpBinding>
        <binding name="myBindingForLargeData" maxReceivedMessageSize="5242880" maxConnections="10">
          <readerQuotas maxDepth="64" maxStringContentLength="5242880" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="WCFService.ServiceBehavior"
        name="WCFService.CollectorService">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="myBindingForLargeData"
          name="netTcpEndPoint" contract="WCFService.ICollectorService" />
        <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
          name="mexTcpEndPoint" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8010/WCFService.CollectorService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFService.ServiceBehavior">
          <serviceMetadata httpGetEnabled="False"/>
          <serviceDebug includeExceptionDetailInFaults="True" />
          <serviceThrottling
          maxConcurrentCalls="32"
          maxConcurrentSessions="32"
          maxConcurrentInstances="32"
           />
        </behavior>
      </serviceBehaviors>
    </behaviors>
</system.serviceModel>
like image 616
Bravo Avatar asked Jan 09 '12 13:01

Bravo


4 Answers

Thanks for all your help. i got the answer after few days of some research and trial n error method :) well i know i am late to post the answer, but i think its better late than never.

So Here's the solution

i had to make some changes in my configuration files (both client & server)

On the client side i added <security> tag as shown below

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="netTcpEndPoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="5242880" maxBufferSize="5242880" maxConnections="15" maxReceivedMessageSize="5242880">
          <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
         <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://xx.xx.xx.xx:8010/WCFService.CollectorService/" binding="netTcpBinding" bindingConfiguration="netTcpEndPoint" contract="CloudAdapter.CloudCollectorService.ICollectorService" name="netTcpEndPoint">
      </endpoint>
    </client>
  </system.serviceModel>

and also added the same tag on the server side (WCF service configuration), as shown below

<bindings>
  <netTcpBinding>
    <binding name="myBindingForLargeData" maxReceivedMessageSize="5242880" maxConnections="10">
      <readerQuotas maxDepth="64" maxStringContentLength="5242880" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
         <security mode="Transport">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
        <message clientCredentialType="Windows" />
      </security>
    </binding>
  </netTcpBinding>
</bindings>

Hope this help a person in need :)

So the KEY is to make the <security> tag same over the client and the server configuration files.

like image 109
Bravo Avatar answered Nov 15 '22 11:11

Bravo


Basically what is happening is that your calling service doesn't have the appropriate credentials, like you would have when calling from WinForms. What you need is some impersonation. It takes a bit of setting up, and is kind of annoying, but it will work.

Luckily MSDN has a nice little walkthrough.
http://msdn.microsoft.com/en-us/library/ms731090.aspx

There is some more general information on the topic here:
http://msdn.microsoft.com/en-us/library/ms730088.aspx

UPDATE:
Setting impersonation flags is not enough. You have to actually impersonate a credential to make it work. For example:

  // Let's assume that this code is run inside of the calling service.
  var winIdentity = ServiceSecurityContext.Current.WindowsIdentity;
  using (var impContext = winIdentity.Impersonate())
  {
    // So this would be the service call that is failing otherwise.
    return MyService.MyServiceCall();
  }
like image 4
A.R. Avatar answered Nov 15 '22 11:11

A.R.


Check out my answer on this post The server has rejected the client credentials.

Note the security node.

<bindings>
  <netTcpBinding>
    <binding name="customTcpBinding" maxReceivedMessageSize="20480000" transferMode="Streamed" >
      <security mode="None"></security>
    </binding>
  </netTcpBinding>
</bindings>
like image 2
spinner_den_g Avatar answered Nov 15 '22 11:11

spinner_den_g


What is the authentication mode you are using on your WCF Service? Seems like the winform app is running and providing the correct credentials while your windows service is not running with the specified privileges or the credentials being passed are not valid. Try to inspect your request using Fiddler when made from you winforms vs Windwos service and see the difference.

like image 1
Rajesh Avatar answered Nov 15 '22 13:11

Rajesh