2016-07-22 3 views
1

Ich muss WCF-Dienst schreiben mit TLS 1.2.Ich muss nur dieses Sicherheitsprotokoll verwenden und (wie ich denke) verweigern Verbindungen mit anderen sicheren Protokolltypen. Ich habe ein Zertifikat erstellt. Bind es zum Hafen. Https funktioniert gut. Ich lese überall, dass ich die nächste Zeichenfolge schreiben muss:Wie sichere Protokoll in WCF-Dienst zu beschränken

Ok, ich schrieb es, aber hatte keine Wirkung. Serviceseite Code:

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 enthält:

<?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> 

Client-Seite Code:

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(); 
     } 
    } 
} 

Wie Sie auf Serviceseite sehen i-Sicherheitsprotokoll TLS 1.2 festgelegt haben. Auf Clientseite habe ich das Sicherheitsprotokoll auf Ssl3 eingestellt. Ich warte darauf, dass der Dienst die Verbindung zum Client ablehnt, da der Server arbeiten und die Clients akzeptieren muss, die nur mit dem Sicherheitsprotokoll Tls 1.2 arbeiten. Aber ich bekomme dieses Ergebnis nicht. Client verbindet und funktioniert gut. Was ist das Problem?

Ich verstehe, dass ich einige Einstellungen auf IIS ändern kann, nur Tls 1.2 zu verwenden. Aber ich mache Self-Hosting-Service und das ist das Problem.

+0

Es gibt keine Verbindung zwischen Ihrem 'ServicePointManager' Objekt und der WCF-Dienst/Client, die ich sehen kann. Ich bin mir nicht sicher, wie Sie die beiden verbinden würden, aber wie Ihr aktueller Code zeigt, weisen Sie das Protokoll keinem bestimmten URI zu. – Tim

+0

@Tim, ich habe baseaddress in app.config festgelegt. Und Service mit diesem URI. Wie kann ich eine Verbindung zwischen ServicePointManager und meinem WCF-Dienst herstellen? Wie ich weiß, beeinflusst ServicePointManager alle Verbindungen in der aktuellen AppDomain. Ist es falsch? –

+0

Ich sehe mir das gleiche Problem an. Jeder empfiehlt das Festlegen der System.Net.ServicePointManager.SecurityProtocol-Eigenschaft, aber es ist nicht klar, wo und wann dies in einem WCF-Dienst (regulärer Typ, nicht Konsolenhost) zu tun ist, und es wird nicht erwähnt, wie es in der Konfigurationsdatei richtig gemacht wird . – PJ7

Antwort

1

Es kann nicht für Server mit ServicePointManager.SecurityProtocol -Option, die zur Verbindung mit etw durch ein bestimmtes Sicherheitsprotokoll verwendet wird. Sie können einige Sicherheitsprotokolle für eine separate Anwendung nicht deaktivieren. Sie können Verbindungen für den gesamten Server zulassen oder deaktivieren. Wenn u alle Protokolle außer TLS 1.2 deaktivieren möchten u müssen Registrierungs Fenster öffnen und den nächsten Schlüssel herausfinden:

HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\ 

und legen Sie die nächsten Werte für jedes Protokoll in Schlüssel [Server]: DisabledByDefault = 1, Enabled = 0

How to enable TLS