我需要使用TLS 1.2编写WCF服务。我只需要使用此安全协议,并且(我认为)拒绝与其他安全协议类型的连接。我已经创建了证书。将它绑定到端口。 Https运作良好。我到处读到我需要写下一串代码:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
好的,我写了,但没有效果。服务端代码:
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Net;
using System.ServiceModel;
using System.Runtime.Serialization;
using static System.Console;
namespace ConsoleHost
{
public class DistributorValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
throw new SecurityTokenException("Both username and password required");
if (userName != "login" || password != "pass")
throw new FaultException($"Wrong username ({userName}) or password ");
}
}
public class Service1 : IService1
{
public string GetData(int value)
{
return $"You entered: {value}";
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException(nameof(composite));
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
[DataContract]
public class CompositeType
{
[DataMember]
public bool BoolValue { get; set; } = true;
[DataMember]
public string StringValue { get; set; } = "Hello ";
}
class Program
{
static void Main(string[] args)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServiceHost host = new ServiceHost(typeof(Service1));
host.Open();
WriteLine("Press any key to stop server...");
ReadLine();
}
}
}
App.config包含:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<services>
<service name="ConsoleHost.Service1">
<host>
<baseAddresses>
<add baseAddress = "https://localhost:8734/Service1/" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ConsoleHost.IService1" bindingConfiguration="securityBinding">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="securityBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" />
<!--establishSecurityContext="false" />-->
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ConsoleHost.DistributorValidator,ConsoleHost"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
客户端代码:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
Service1Client client = new Service1Client();
client.ClientCredentials.UserName.UserName = "login";
client.ClientCredentials.UserName.Password = "pass";
Console.WriteLine(client.GetData(10));
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
if (ex.InnerException != null)
{
Console.WriteLine("Inner: " + ex.InnerException.Message);
if (ex.InnerException.InnerException != null)
Console.WriteLine("Inner: " + ex.InnerException.InnerException.Message);
}
}
Console.ReadLine();
}
}
}
正如您在服务方面所看到的,我已将安全协议设置为Tls 1.2。在客户端,我已将安全协议设置为Ssl3。我正在等待该服务将拒绝客户端连接,因为服务器必须工作并接受仅使用Tls 1.2安全协议的客户端。但我没有得到这个结果。客户端连接并运行良好。有什么问题?
我知道我可以在IIS上更改某些设置以仅使用Tls 1.2。但我正在自我托管wcf服务,这就是问题所在。
答案 0 :(得分:1)
使用ServicePointManager.SecurityProtocol选项可以为服务器完成,该选项用于通过特定的安全协议连接到某个安全协议。您无法为单独的应用程序关闭某些安全协议,您可以允许或禁止整个服务器的连接。如果你想要禁用除TLS 1.2之外的所有协议,你必须打开注册表窗口并找到下一个密钥:
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\
并在key [Server]中设置每个协议的下一个值:DisabledByDefault = 1,Enabled = 0