I am trying to get WCF communication to work over a TLS connection. I am using Mono 5.20.1.19 on Ubuntu 18.04, although I would hope that a solution would work on Windows too.
Consider a basic interface like this:
IExample.cs:
using System;
using System.ServiceModel;
namespace Example
{
[ServiceContract]
public interface IExample
{
[OperationContract]
string Greet();
}
}
I have a server that sets up ServiceHost for an implementation of the interface:
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();
}
}
}
}
Note that SecurityMode.Transport
is specified for the NetTcpBinding, and TcpClientCredentialType.Certificate
for the client credential type. I also specify a certificate which I installed to the My
certificate store, in addition to the private key for the certificate.
Now the client:
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());
}
}
}
Note that in the client, the NetTcpBinding's security mode is set to None
, and no client certificate is specified.
We can build the two programs:
$ 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.
Now, if we run Server.exe, leave it open, and then in a different session run Client.exe, the server prints the message Greet() called
, while the client prints Hello!
.
My confusion is why the connection is successful. I would expect that since the server's binding is set to Transport
, then it should require a TLS connection; however it does not seem that TLS is being used, as no client certificate is being specified.
How can I change the server portion of the code to require TLS connections?
First, I could not reproduce your issue, the following error occurred when I call the service locally.
Then, NetTcpBinding can use windows credentials or certificates to ensure transport layer security.
Please refer to the posts I have replied to before.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/7b300a92-8533-4afe-9e8b-3f38138dd23b/ssltsl-with-nettcpbinding?forum=wcf
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.