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[] 开发者_如何学Pythonargs)
{
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));
}
}
}
}
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;
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).
精彩评论