Search code examples
c#wcfwcf-bindingwcf-securitywcf-client

Problem authenticating with WCF service cross domain


I'm new to WCF and its security so was looking for some help on a problem I'm having.

I have a WCF service that to be deployed to every machine in a small domain. The WCF service is to be hosted in a Windows Service since it has methods in it that need to be invoked elevated. The service is very draft at the moment (it exposes meta-data - but I believe this is to be turned off later - is this possible?). It uses the net.tcp binding - The App.Config of the service is shown below:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="SvcBehavior" name="Microsoft.ServiceModel.Samples.Svc">
        <endpoint address="" binding="netTcpBinding"
          contract="Microsoft.ServiceModel.Samples.ISvc" />
        <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://*:8100/ServiceModelSamples/service" />
          </baseAddresses>
          <timeouts closeTimeout="00:10:00" openTimeout="00:10:00" />
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SvcBehavior">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

For a client, I have a Winforms C# application. The application serves 2 functions, it pulls static information from the service and then gives the user an option to authenticate and call the administrative methods. Therefore, the authentication is done at client level.

I am using Channelfactory to connect to the service since the hostname is variable (user is prompted for it on client start-up) and the app.config file for the client is shown below - its virtually empty:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
     </bindings>
    <client />
  </system.serviceModel>
</configuration>

The channelfactory code is:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples", ConfigurationName = "ISvc")]


ChannelFactory<ISvc> myChannelFactory = new ChannelFactory<ISvc>(new NetTcpBinding(), "net.tcp://" + HostName + ":8100/ServiceModelSamples/service");
        public static ISvc client = null;

I have an interface that descrives the methods in the service as well.

The main problem I am having is this. Say there is Machine1 and Machine2 running on domainA. Lets assume that Machine1 hosts the service and Machine2 runs the client.

When I connect to the service using a domain account domainA\User, the service works fine but say I have a local user on Machine2 and want to connect to the service as Machine2\LocalUser, I get the following error message:

The server has rejected the client credentials.

I have tried experimenting with setting the security mode to none (not something im keen on doing) but then I get an error saying the client and service have a configuration mismatch.

Is there something I can do to fix this? Also, what would happen if the service running on domainA\Machine1 was called by a user from another domain - say domainB\User2 ?

Thanks in advance - Id appreciate some insight into this!

Chada


Solution

  • If you turn off security on the service you must turn in off on the client as well. If you configure client in code you must set the same configuration for new instance of NetTcpBinding as you do on the service in configuration file.

    When Windows security is used (default for NetTcpBinding) MachineB cannot authenticate local accounts from MachineA (there were some tricks with duplicate local users but I don't know if they work with WCF as well). That is why you have a domain. Cross domain windows authentication requires trust between domains.

    If you need to authenticate cross domain users or local users you cannot use Windows authentication. There are other authentication mechanism but they require configuring certificate (at least on the service) and use either client certificate or user name and password for client authentication.