Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF With NetTCP across machines on the same network

I'm trying to implement some cross process communication that is between multiple computers and one server on the same network. What I'm trying right now is to use WCF with NetTcpBinding, hosted within my application which works on the same machine, but when I try to connect from another machine it throws a SSPI security error.

I've found lots of examples of doing this cross-machine, but all involve an app.config file which I would REALLY like to avoid. I want to be able to embed this functionality in a DLL that has not other dependencies (i.e. config files) for which I can just pass into it all of the necessary server addresses, etc and it will work. Is there anyway to setup this security (via the endpoints, etc) purely in code?

I'm testing this all out with the code below:

SERVER:

using System;
using System.ServiceModel;

namespace WCFServer
{
  [ServiceContract]
  public interface IStringReverser
  {
    [OperationContract]
    string ReverseString(string value);
  }

  public class StringReverser : IStringReverser
  {
    public string ReverseString(string value)
    {
      char[] retVal = value.ToCharArray();
      int idx = 0;
      for (int i = value.Length - 1; i >= 0; i--)
        retVal[idx++] = value[i];

      string result = new string(retVal);
      Console.WriteLine(value + " -> " + result);
      return result;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
        var uri = "net.tcp://" + System.Net.Dns.GetHostName() + ":9985";
        Console.WriteLine("Opening connection on: " + uri);

      using (ServiceHost host = new ServiceHost(
        typeof(StringReverser),
        new Uri[]{
          new Uri("net.tcp://" + System.Net.Dns.GetHostName() + ":9985")
        }))
      {
        host.AddServiceEndpoint(typeof(IStringReverser),
          new NetTcpBinding(),
          "TcpReverse");

        host.Open();

        Console.WriteLine("Service is available. " +  
          "Press <ENTER> to exit.");
        Console.ReadLine();

        host.Close();
      }
    }
  }
}

CLIENT:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WCFClient
{
  [ServiceContract]
  public interface IStringReverser
  {
    [OperationContract]
    string ReverseString(string value);
  }

  class Program
  {
    static void Main(string[] args)
    {
        var ep = "net.tcp://SERVER:9985/TcpReverse";
      ChannelFactory<IStringReverser> pipeFactory =
        new ChannelFactory<IStringReverser>(
          new NetTcpBinding(),
          new EndpointAddress(
            ep));

      IStringReverser pipeProxy =
        pipeFactory.CreateChannel();

      Console.WriteLine("Connected to: " + ep);
      while (true)
      {
        string str = Console.ReadLine();
        Console.WriteLine("pipe: " + 
          pipeProxy.ReverseString(str));
      }
    }
  }
}
like image 749
Adam Haile Avatar asked Aug 01 '11 20:08

Adam Haile


People also ask

What is WCF TCP port Sharing?

Windows Communication Foundation (WCF) provides a new TCP-based network protocol (net. tcp://) for high-performance communication. WCF also introduces a new system component, the Net. TCP Port Sharing Service that enables net. tcp ports to be shared across multiple user processes.

How to enable Net TCP port Sharing service?

In the Name column of the list of services, right-click the Net. Tcp Port Sharing Service, and select Properties from the menu. To enable the manual start-up of the service, in the Properties window select the General tab, and in the Startup type box select Manual, and then click Apply.

What is Nettcp?

The NetTcpBinding generates a run-time communication stack by default, which uses transport security, TCP for message delivery, and a binary message encoding. This binding is an appropriate Windows Communication Foundation (WCF) system-provided choice for communicating over an Intranet.


2 Answers

Security is normally configured on the binding. You are using NetTcpBinding with its defaults which means that Transport security is enabled.

On both, server and client, you should assign the NetTcpBinding instance to a local variable so that you can change the security (and possibly other) settings, and then use that variable when calling AddServiceEndpoint or when creating the ChannelFactory.

Sample:

var binding = new NetTcpBinding();
// disable security:
binding.Security.Mode = SecurityMode.None;
like image 90
mthierba Avatar answered Sep 20 '22 17:09

mthierba


This is probably an issue with the SPN that your service is running under. It's most likely a machine account instead of a domain account. There's more information in this thread.

UPDATE: There's information in there about setting the SPN programmatically, but it's buried a few clicks in... here's a direct link (see the last section of the page).

like image 44
Rick Liddle Avatar answered Sep 19 '22 17:09

Rick Liddle