我正在尝试使WCF通信能够通过TLS连接工作。我希望在Ubuntu 18.04上使用Mono 5.20.1.19,尽管我希望该解决方案也能在Windows上运行。
考虑这样的基本接口:
IExample.cs:
using System;
using System.ServiceModel;
namespace Example
{
[ServiceContract]
public interface IExample
{
[OperationContract]
string Greet();
}
}
我有一台服务器,它为接口的实现设置了ServiceHost:
Server.cs:
using System;
using System.Net;
using System.Net.Security;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.Security.Cryptography.X509Certificates;
namespace Example
{
public class ExampleImpl : IExample
{
public string Greet()
{
Console.WriteLine("Greet() called");
return "Hello!";
}
}
public static class Program
{
public static void Main(string[] args)
{
using(var host = new ServiceHost(typeof(ExampleImpl), new Uri("net.tcp://localhost:5555"))){
var binding = new NetTcpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
binding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;
host.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindBySubjectName,
"server");
host.AddServiceEndpoint(typeof(IExample), binding, "Example");
host.Open();
Console.WriteLine("listening at :5555");
Console.WriteLine("Press Enter to end the program");
Console.ReadLine();
}
}
}
}
请注意,为NetTcpBinding指定了
SecurityMode.Transport
,为客户端凭据类型指定了TcpClientCredentialType.Certificate
。除了证书的私钥以外,我还指定了我安装到My
证书存储区的证书。现在客户:
Client.cs:
using System;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace Example
{
public static class Program
{
public static void Main(string[] args)
{
var binding = new NetTcpBinding(SecurityMode.None);
var factory = new ChannelFactory<IExample>(binding, new EndpointAddress("net.tcp://localhost:5555/Example"));
var obj = factory.CreateChannel();
Console.WriteLine(obj.Greet());
}
}
}
请注意,在客户端中,NetTcpBinding的安全模式设置为
None
,并且未指定客户端证书。我们可以构建两个程序:
$ csc Server.cs IExample.cs
Microsoft (R) Visual C# Compiler version 2.8.2.62916 (2ad4aabc)
Copyright (C) Microsoft Corporation. All rights reserved.
$ csc Client.cs IExample.cs
Microsoft (R) Visual C# Compiler version 2.8.2.62916 (2ad4aabc)
Copyright (C) Microsoft Corporation. All rights reserved.
现在,如果我们运行Server.exe,请将其保持打开状态,然后在另一个会话中运行Client.exe,服务器将显示消息
Greet() called
,而客户端将显示Hello!
。我的困惑是为什么连接成功。我希望由于服务器的绑定设置为
Transport
,因此它应该需要TLS连接。但是似乎没有使用TLS,因为未指定客户端证书。如何更改代码的服务器部分以要求TLS连接?
最佳答案
首先,我无法重现您的问题,当我在本地调用服务时发生以下错误。
然后,NetTcpBinding可以使用Windows凭据或证书来确保传输层安全性。
请参阅我之前回复的帖子。
https://social.msdn.microsoft.com/Forums/vstudio/en-US/7b300a92-8533-4afe-9e8b-3f38138dd23b/ssltsl-with-nettcpbinding?forum=wcf
关于c# - Mono下TLS上的WCF,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55976023/