Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Communication Foundation .NET Discussion :

SSL avec des services WCF auto hébergés


Sujet :

Windows Communication Foundation .NET

  1. #1
    Membre du Club
    SSL avec des services WCF auto hébergés
    Bonjour,

    J'auto-héberge un service REST WCF avec la classe ServiceHost, en utilisant HTTPS et la sécurité par certificat. Le tout se lance correctement, mais mon souci est que tout le monde a accès à ce service, y compris les machines qui n'ont pas le certificat client d'installé.

    J'ouvre bien le port 4453 du service avec netsh :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    netsh http add urlacl url=https://+:4453/ user=\Everyone   ou "Tout le monde" en français
    netsh http add sslcert ipport=0.0.0.0:4453 certhash=xxxxxx appid={5d1c536e-3fac-4500-8b08-e8aae9f7e81b} clientcertnegotiation=enable


    Voici ma config :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <startup> 
          <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
      </startup>
      <system.serviceModel>
        <bindings>
          <webHttpBinding>
            <binding name="webHttpBindingConfiguration" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:01:00" 
                     sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
                     maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" 
                     transferMode="Buffered" useDefaultWebProxy="true">
              <security mode="Transport">
                <transport clientCredentialType="None" proxyCredentialType="None"/>
              </security>
            </binding>
          </webHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="serviceBehavior">
              <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior name="endpointBehavior">
              <webHttp/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <protocolMapping>
          <add binding="webHttpBinding" scheme="https"/>
        </protocolMapping>
        <services>
          <service behaviorConfiguration="serviceBehavior" name="WV2.BusinessService.Implementation.WV2BusinessService">
            <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingConfiguration" 
                     behaviorConfiguration="endpointBehavior" contract="WV2.BusinessService.Interface.IWV2BusinessService"/>
          </service>
        </services>
      </system.serviceModel>
    </configuration>


    L'hébergement du serveur :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                    string serviceAddress = "https://localhost:4453/WV2BusinessService";
                    Uri baseAddress = new Uri(serviceAddress);
     
                    serviceHost = new ServiceHost(typeof(WV2.BusinessService.Implementation.WV2BusinessService), baseAddress); 
     
                    serviceHost.Open();


    Et le client :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
            private void Button1_Click(object sender, RoutedEventArgs e)
            {
                ServicePointManager.ServerCertificateValidationCallback = delegate (Object obj, X509Certificate certificate, X509Chain chain, System.Net.Security.SslPolicyErrors errors)
                {
                    return true;
                };
     
                try
                {
                    var businessServiceChannelFactory = new ChannelFactory<IWV2BusinessService>("WV2BusinessServiceClientEndpoint",
                        new EndpointAddress("https://localhost:4453/WV2BusinessService"));
     
                    var certPath = @"CertificatDev.cer";
                    if (System.IO.File.Exists(certPath))
                    {
                        var winstoxCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath, "monmotdepass");
                        businessServiceChannelFactory.Credentials.ClientCertificate.Certificate = winstoxCertificate;
                    }
     
                    using (var client = businessServiceChannelFactory.CreateChannel())
                    {
                        var result = client.CheckEntityBeforeSave(new WV2.BusinessService.Model.Entity());
                        MessageBox.Show(result.Select(x => x.Message).Aggregate((s1, s2) => s1 + "\n" + s2));
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }


    Comment se fait-il que les machines sans certificat accèdent à mon service ?

  2. #2
    Membre du Club
    Bon, j'ai mis en place la sécurité par certificat :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
              <security mode="Transport">
                <transport clientCredentialType="Certificate" proxyCredentialType="None"/>
              </security>


    Et j'ai ajouté un CustomCertificateValidator qui hérite de la classe X509CertificateValidator :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            <behavior name="serviceBehavior">
              <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <serviceCredentials>
                <clientCertificate>
                  <authentication certificateValidationMode="Custom" customCertificateValidatorType="WV2BusinessService.zX509CertificateValidator, WV2BusinessService" />
                </clientCertificate>
              </serviceCredentials>
            </behavior>


    Dans la classe zX509CertificateValidator je vérifie le hash du certificat.

    Maintenant j'ai un autre problème. Les machines distantes ne peuvent accéder au service même avec le certificat installé et en plus fourni dans les crédentials du client de service.

    A suivre...