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

5

12

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>
Vexatious answered 9/1, 2012 at 13:47 Comment(0)
V
6

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.

Vexatious answered 5/3, 2012 at 15:39 Comment(0)
D
4

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();
  }
Destination answered 9/1, 2012 at 13:52 Comment(2)
Updated the Question please checkVexatious
OK, you have to actually tell it whom it is to impersonate. You can't just set the flag and expect it to magically impersonate someone. Read the materials presented in the second link.Destination
M
2

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>
Manara answered 13/1, 2012 at 3:4 Comment(1)
Explicitly adding <security mode="None"></security> worked for me as well. I got the "server has rejected the client credentials" error when running my client application from machine A, but not from machine B. It turns out that this was because machine B had the same Windows credentials (user name and password) as my server machine.Corri
R
1

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.

Roumell answered 9/1, 2012 at 14:19 Comment(3)
i have tried to debug my Windows service, and found the above error when i try open a connection to the Service client. BTW what is Fiddler and is it helpful in my kind of scenario, where i have a WCF service with net.tcp binding. please let me knowVexatious
i have not implemented any security implicitly on the WCF service. might be a default security implementation.Vexatious
@Bravo: Fiddler is a tool that inspects your incoming and outgoing traffic over the network. From the configuration above the service uses net.Tcp. Can i know if its hosted in IIS or self hosted? Also is your windows service on a different machine?Roumell
A
0

For me it helped to set on both sides (client + server) the security mode to None:

NetTcpBinding binding = new NetTcpBinding(); binding.Security.Mode = SecurityMode.None;

(Same answer as from spinner_den_g but in C# - no need to edit the app.config)

Akkad answered 1/11, 2021 at 10:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.