1
votes

What I am trying to achieve, my windows service will run periodically in machine with/without user logon and send updates into remote machine(raw value). On remote machines, WCF service will reply a formatted value (like result) and updates database with raw input asynchonously.

Windows Service Client (WCF Client) => IIS (WCF Service) => Database (asynchonously) Windows Service Client (WCF Client) <= IIS (WCF Service)

What I doing now, I hosted the WCF service in IIS but my windows service (WCF client) is having problem authenticating and connecting to WCF. I am aware that windows service is running under "LOCALSYSTEM" account. But before I call, I impersonate the "NETWORK SERVICE".

  • Is this scenario possible in WCF?

  • What account should I used? Can I hardcode the credentinals in WCF client?

  • I tried a self-signed certificate but I am getting error on IIS side "Keyset not found" when opening the WSDL at the browser

My current bindings: * netTcpBinding * wsHttpBinding

  • How to set each binding that support my objective?

WCF web.config hosted in IIS:

<system.serviceModel>    
<bindings>
  <netTcpBinding>
    <binding name="CustomNetTcpBinding" closeTimeout="00:02:30" openTimeout="00:02:30"
      sendTimeout="00:02:30" listenBacklog="20" maxConnections="20">
      <readerQuotas maxDepth="512" maxStringContentLength="50000" maxArrayLength="50000"
        maxBytesPerRead="50000" maxNameTableCharCount="512" />
      <security mode="Transport" />
    </binding>
  </netTcpBinding>
  <wsHttpBinding>
    <binding name="CustomWsHttpBinding" closeTimeout="00:02:30" openTimeout="00:02:30"
      sendTimeout="00:02:30">
      <readerQuotas maxDepth="512" maxStringContentLength="50000" maxArrayLength="50000"
        maxBytesPerRead="50000" maxNameTableCharCount="512" />
    </binding>
  </wsHttpBinding>
</bindings>
<diagnostics>
  <messageLogging logMalformedMessages="false" logMessagesAtServiceLevel="false"
    logMessagesAtTransportLevel="false" />
</diagnostics>
<services>
  <service behaviorConfiguration="TestAppWcfServiceApp.Service1Behavior"
    name="TestAppWcfServerLib.TestAppServiceComposite2">
    <endpoint address="mexhttp" binding="mexHttpBinding" contract="IMetadataExchange" />
    <endpoint address="nettcp" binding="netTcpBinding" bindingConfiguration="CustomNetTcpBinding"
      contract="TestAppWcfServerLib.ITestAppServiceContract2" />
    <endpoint address="wshttp" binding="wsHttpBinding" bindingConfiguration="CustomWsHttpBinding"
      contract="TestAppWcfServerLib.ITestAppServiceContract2" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8005/TestApp" />
        <add baseAddress="http://localhost/TestApp" />
      </baseAddresses>
      <timeouts openTimeout="00:02:30" />
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="TestAppWcfServiceApp.Service1Behavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>    

WCF client in Windows Service:

 <system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding name="NetTcpBinding_ITestAppServiceContract2" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
                maxReceivedMessageSize="65536">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" 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>
        <wsHttpBinding>
            <binding name="WSHttpBinding_ITestAppServiceContract2" 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">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Message">
                    <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="net.tcp://ServerName/testtools/TestAppServApp.svc/nettcp"
            binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ITestAppServiceContract2"
            contract="proxyClient.ITestAppServiceContract2" name="NetTcpBinding_ITestAppServiceContract2">
            <identity>
                <servicePrincipalName value="host/ServerName" />
            </identity>
        </endpoint>
        <endpoint address="http://ServerName/testtools/TestAppServApp.svc/wshttp"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITestAppServiceContract2"
            contract="proxyClient.ITestAppServiceContract2" name="WSHttpBinding_ITestAppServiceContract2">
            <identity>
                <servicePrincipalName value="host/ServerName" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

My Setup:

  • Development machine: •Windows 7 x64 Enterprise edition •VS2010 SP1 Ultimate

  • Windows 2008 SP2 x86 Enterprise Edition •IIS 7.0 with WAS activated

1
What is it you need to do that forces your windows service to have to run as LOCALSYSTEM - that's a very privileged account that you should only use if you have no other choice. Also can you post the service config so we can see how you are performing authentication, etc. Finally are the machines part of the same domain? - Richard Blewett
Could you not use a normal account and just adjust the ACLs so it has access to what it needs? - Richard Blewett
This is not only what it does. Think as it scanning for a lot of objects like WMI, RSOP, registry, files and PInvoke - altyne
how to post here as formatted in XML? Sorry this is my first time. - altyne
my config will exceeds from characters limit. - altyne

1 Answers

1
votes

You can't use windows authentication reliably between two machines in separate domains. the only way you can achieve this is to have accounts called the same thing with the same password on both machines.The problem is they have no shared trusted security authority who can guarantee the credentials are correct

You should switch to using certificates or usernames for authentication