Guide pratique pour sécuriser les points de terminaison de métadonnées

Les métadonnées d’un service peuvent contenir des informations sensibles sur votre application qu’un utilisateur malveillant peut tirer parti. Les consommateurs de votre service peuvent également nécessiter un mécanisme sécurisé pour obtenir des métadonnées sur votre service. Par conséquent, il est parfois nécessaire de publier vos métadonnées à l’aide d’un point de terminaison sécurisé.

Les points de terminaison de métadonnées sont généralement sécurisés à l’aide des mécanismes de sécurité standard définis dans Windows Communication Foundation (WCF) pour sécuriser les points de terminaison d’application. Pour plus d’informations, consultez Vue d’ensemble de la sécurité.

Cette rubrique décrit les étapes de création d’un point de terminaison sécurisé par un certificat SSL (Secure Sockets Layer) ou, en d’autres termes, un point de terminaison HTTPS.

Pour créer un point de terminaison de métadonnées HTTPS GET sécurisé dans le code

  1. Configurez un port avec un certificat X.509 approprié. Le certificat doit provenir d’une autorité approuvée et doit avoir une utilisation prévue de « Autorisation de service ». Vous devez utiliser l’outil HttpCfg.exe pour attacher le certificat au port. Découvrez comment : configurer un port avec un certificat SSL.

    Important

    L’objet du certificat ou de son système DNS (Domain Name System) doit correspondre au nom de l’ordinateur. Cela est essentiel, car l’une des premières étapes effectuées par le mécanisme HTTPS consiste à vérifier que le certificat est émis dans le même URI (Uniform Resource Identifier) que l’adresse sur laquelle elle est appelée.

  2. Créez une instance de la classe ServiceMetadataBehavior.

  3. Définissez la HttpsGetEnabled propriété de la ServiceMetadataBehavior classe sur true.

  4. Définissez la HttpsGetUrl propriété sur une URL appropriée. Notez que si vous spécifiez une adresse absolue, l’URL doit commencer par le schéma https://. Si vous spécifiez une adresse relative, vous devez fournir une adresse de base HTTPS pour votre hôte de service. Si cette propriété n’est pas définie, l’adresse par défaut est « » ou directement à l’adresse de base HTTPS du service.

  5. Ajoutez l’instance à la collection de comportements que la Behaviors propriété de la ServiceDescription classe retourne, comme indiqué dans le code suivant.

    // Create a new metadata behavior object and set its properties to
    // create a secure endpoint.
    ServiceMetadataBehavior sb = new ServiceMetadataBehavior();
    sb.HttpsGetEnabled = true;
    sb.HttpsGetUrl = new Uri("https://myMachineName:8036/myEndpoint");
    myServiceHost.Description.Behaviors.Add(sb);
    
    myServiceHost.Open();
    
    ' Create a new metadata behavior object and set its properties to 
    ' create a secure endpoint. 
    Dim sb As New ServiceMetadataBehavior()
    
    With sb
        .HttpsGetEnabled = True
        .HttpsGetUrl = New Uri("https://myMachineName:8036/myEndpoint")
    End With
    
    With myServiceHost
        .Description.Behaviors.Add(sb)
        .Open()
    End With
    

Pour créer un point de terminaison de métadonnées HTTPS GET sécurisé dans la configuration

  1. Ajoutez un <élément de comportement> à l’élément <system.serviceModel> du fichier de configuration de votre service.

  2. Ajoutez l'<élément serviceBehaviors> à l’élément <behaviors>.

  3. Ajoutez un <élément de comportement> à l’élément <serviceBehaviors> .

  4. Définissez l’attribut name de l’élément <behavior> sur une valeur appropriée. L'attribut name est obligatoire. L’exemple ci-dessous utilise la valeur mySvcBehavior.

  5. Ajoutez un <serviceMetadata> à l’élément <behavior> .

  6. Définissez l’attribut httpsGetEnabled de l’élément <serviceMetadata> sur true.

  7. Définissez l’attribut httpsGetUrl de l’élément <serviceMetadata> sur une valeur appropriée. Notez que si vous spécifiez une adresse absolue, l’URL doit commencer par le schéma https://. Si vous spécifiez une adresse relative, vous devez fournir une adresse de base HTTPS pour votre hôte de service. Si cette propriété n’est pas définie, l’adresse par défaut est « » ou directement à l’adresse de base HTTPS du service.

  8. Pour utiliser le comportement avec un service, définissez l’attribut behaviorConfiguration de l’élément <de service> sur la valeur de l’attribut de nom de l’élément de comportement. Le code de configuration suivant illustre un exemple complet.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <system.serviceModel>
      <behaviors>
       <serviceBehaviors>
        <behavior name="mySvcBehavior">
         <serviceMetadata httpsGetEnabled="true"
              httpsGetUrl="https://localhost:8036/calcMetadata" />
        </behavior>
       </serviceBehaviors>
      </behaviors>
     <services>
      <service behaviorConfiguration="mySvcBehavior"
            name="Microsoft.Security.Samples.Calculator">
       <endpoint address="http://localhost:8037/ServiceModelSamples/calculator"
       binding="wsHttpBinding" bindingConfiguration=""
       contract="Microsoft.Security.Samples.ICalculator" />
      </service>
     </services>
    </system.serviceModel>
    </configuration>
    

Exemple

L’exemple suivant crée une instance d’une ServiceHost classe et ajoute un point de terminaison. Le code crée ensuite une instance de la ServiceMetadataBehavior classe et définit les propriétés pour créer un point d’échange de métadonnées sécurisé.

WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.Windows;

// Create the Type instances for later use and the URI for
// the base address.
Type contractType = typeof(ICalculator);
Type serviceType = typeof(Calculator);
Uri baseAddress = new
    Uri("http://localhost:8037/serviceModelSamples/");

// Create the ServiceHost and add an endpoint.
ServiceHost myServiceHost =
    new ServiceHost(serviceType, baseAddress);
myServiceHost.AddServiceEndpoint
    (contractType, myBinding, "secureCalculator");
// Create a new metadata behavior object and set its properties to
// create a secure endpoint.
ServiceMetadataBehavior sb = new ServiceMetadataBehavior();
sb.HttpsGetEnabled = true;
sb.HttpsGetUrl = new Uri("https://myMachineName:8036/myEndpoint");
myServiceHost.Description.Behaviors.Add(sb);

myServiceHost.Open();
// Use the GetHostEntry method to return the actual machine name.
string machineName = System.Net.Dns.GetHostEntry("").HostName ;
Console.WriteLine($"Listening @ {machineName}:8037/serviceModelSamples/");
Console.WriteLine("Press Enter to close the service");
Console.ReadLine();
myServiceHost.Close();
Dim myBinding As New WSHttpBinding()
With myBinding.Security
    .Mode = SecurityMode.Message
    .Message.ClientCredentialType = MessageCredentialType.Windows
End With

' Create the Type instances for later use and the URI for 
' the base address.
Dim contractType = GetType(ICalculator)
Dim serviceType = GetType(Calculator)
Dim baseAddress As New Uri("http://localhost:8037/serviceModelSamples/")

' Create the ServiceHost and add an endpoint. 
Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")

' Create a new metadata behavior object and set its properties to 
' create a secure endpoint. 
Dim sb As New ServiceMetadataBehavior()

With sb
    .HttpsGetEnabled = True
    .HttpsGetUrl = New Uri("https://myMachineName:8036/myEndpoint")
End With

With myServiceHost
    .Description.Behaviors.Add(sb)
    .Open()
End With

' Use the GetHostEntry method to return the actual machine name.
Dim machineName = System.Net.Dns.GetHostEntry("").HostName
Console.WriteLine("Listening @ {0}:8037/serviceModelSamples/", machineName)
Console.WriteLine("Press Enter to close the service")
Console.ReadLine()
myServiceHost.Close()

Compilation du code

L’exemple de code utilise les espaces de noms suivants :

Voir également