Comment : sécuriser un service à l'aide d'informations d'identification Windows

Cette rubrique décrit comment activer la sécurité de transfert sur un service Windows Communication Foundation (WCF) résidant dans un domaine Windows et appelé par des clients du même domaine. Pour plus d'informations sur le sujet suivant ce scénario, consultez Sécurité de transport avec l'authentification Windows. Pour obtenir un exemple d'application, consultez l'exemple WSHttpBinding.

Cette rubrique suppose que vous avez une interface de contrat existante et que l'implémentation est déjà définie et s'ajoute à cela. Vous pouvez également modifier un service et un client existants.

Vous pouvez sécuriser complètement un service avec les informations d'identification Windows dans le code. Vous pouvez également omettre un peu du code en utilisant un fichier de configuration. Cette rubrique décrit les deux approches. Veillez à n'en utiliser qu'une seule, pas les deux.

Les trois premières procédures indiquent comment sécuriser le service à l'aide du code. Les quatrième et cinquième procédures indiquent comment le faire avec un fichier de configuration.

Utilisation du code

L'intégralité du code du service et du client est présentée dans la section Exemple à la fin de cette rubrique.

La première procédure vous guide tout au long de la création et la configuration d'une classe WSHttpBinding dans le code. La liaison utilise le transport HTTP. La même liaison est utilisée sur le client.

Pour créer un WSHttpBinding qui utilise des informations d'identification Windows et la sécurité de message

  1. Le code de cette procédure est inséré au début de la méthode Run de la classe Test dans le code de service indiqué à la section Exemple.

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

  3. Affectez la valeur Message à la propriété Mode de la classe WsHttpSecurity.

  4. Affectez la valeur Windows à la propriété ClientCredentialType de la classe MessageSecurityOverHttp.

  5. Le code de cette procédure se présente comme suit :

    Dim myBinding As New WSHttpBinding()
    myBinding.Security.Mode = SecurityMode.Message
    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
    
    // First procedure:
    // create a WSHttpBinding that uses Windows credentials and message security
    WSHttpBinding myBinding = new WSHttpBinding();
    myBinding.Security.Mode = SecurityMode.Message;
    myBinding.Security.Message.ClientCredentialType =
        MessageCredentialType.Windows;
    

Utilisation de la liaison dans un service

Il s'agit de la deuxième procédure, qui indique comment utiliser la liaison dans un service auto-hébergé. Pour plus d'informations sur le sujet suivant les services d'hébergement, consultez Hébergement de services.

Pour utiliser une liaison dans un service

  1. Insérez le code de cette procédure après celui de la procédure précédente.

  2. Créez une variable Type nommée contractType et assignez-lui le type de l'interface (ICalculator). Lorsque vous utilisez Visual Basic, utilisez l'opérateur GetType ; lorsque vous utilisez C#, utilisez le mot clé typeof.

  3. Créez une deuxième variable Type nommée serviceType et assignez-lui le type du contrat implémenté (Calculator).

  4. Créez une instance de la classe Uri nommée baseAddress avec l'adresse de base du service. L'adresse de base doit avoir un schéma qui correspond au transport. Dans ce cas, le schéma de transport est HTTP et l'adresse inclut l'URI (Uniform Resource Identifier) spécial « localhost » et un numéro de port (8036), ainsi qu'une adresse de point de terminaison de base (serviceModelSamples/) : https://localhost:8036/serviceModelSamples/.

  5. Créez une instance de la classe ServiceHost avec les variables serviceType et baseAddress.

  6. Ajoutez un point de terminaison au service à l'aide du contractType, de la liaison et d'un nom de point de terminaison (secureCalculator). Un client doit concaténer l'adresse de base et le nom de point de terminaison lors du lancement d'un appel au service.

  7. Appelez la méthode Open pour démarrer le service. Le code de cette procédure est indiqué ici :

    ' Create the Type instances for later use and the URI for 
    ' the base address.
    Dim contractType As Type = GetType(ICalculator)
    Dim serviceType As Type = GetType(Calculator)
    Dim baseAddress As New Uri("https://localhost:8036/serviceModelSamples/")
    
    ' Create the ServiceHost and add an endpoint, then start
    ' the service.
    Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
    myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")
    myServiceHost.Open()
    
    // 2nd Procedure:
    // Use the binding in a service
    // 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("https://localhost:8036/SecuritySamples/");
    
    // Create the ServiceHost and add an endpoint, then start
    // the service.
    ServiceHost myServiceHost =
        new ServiceHost(serviceType, baseAddress);
    myServiceHost.AddServiceEndpoint
        (contractType, myBinding, "secureCalculator");
    
    //enable metadata
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    myServiceHost.Description.Behaviors.Add(smb);
    
    myServiceHost.Open();
    

Utilisation de la liaison sur un client

Cette procédure indique comment générer un proxy qui communique avec le service. Le proxy est généré avec Outil Service Model Metadata Tool (Svcutil.exe), qui utilise les métadonnées du service pour le créer.

Cette procédure crée également une instance de la classe WSHttpBinding pour communiquer avec le service, puis appelle ce dernier.

Cet exemple utilise uniquement du code pour créer le client. Vous pouvez aussi, si vous le souhaitez, utiliser un fichier de configuration, indiqué dans la section qui suit cette procédure.

Pour utiliser une liaison sur un client avec le code

  1. Utilisez l'outil SvcUtil.exe pour générer le code du proxy à partir des métadonnées du service. Pour plus d'informations, consultez Comment : créer un client Windows Communication Foundation. Le code du proxy généré hérite de la classe ClientBase, ce qui garantit que chaque client possède les constructeurs, méthodes et propriétés nécessaires pour communiquer avec un service WCF. Dans cet exemple, le code généré inclut la classe CalculatorClient, qui implémente l'interface ICalculator, activant ainsi la compatibilité avec le code de service.

  2. Le code de cette procédure est inséré au début de la méthode Main du programme client.

  3. Créez une instance de la classe WSHttpBinding et affectez à son mode de sécurité la valeur Message et à son type d'informations d'identification client la valeur Windows. L'exemple nomme la variable clientBinding.

  4. Créez une instance de la classe EndpointAddress nommée serviceAddress. Initialisez l'instance avec l'adresse de base concaténée avec le nom de point de terminaison.

  5. Créez une instance de la classe de client générée avec les variables serviceAddress et clientBinding.

  6. Appelez la méthode Open, comme illustré dans le code suivant :

  7. Appelez le service et affichez les résultats.

    Dim b As New WSHttpBinding(SecurityMode.Message)
    b.Security.Message.ClientCredentialType = MessageCredentialType.Windows
    
    Dim ea As New EndpointAddress("net.tcp://machinename:8036/endpoint")
    Dim cc As New CalculatorClient(b, ea)
    cc.Open()
    
    ' Alternatively, use a binding name from a configuration file generated by the
    ' SvcUtil.exe tool to create the client. Omit the binding and endpoint address 
    ' because that information is provided by the configuration file.
    ' CalculatorClass cc = new CalculatorClient("ICalculator_Binding")
    
    // 3rd Procedure:
    //  Creating a binding and using it in a service
    
    // To run using config, comment the following lines, and uncomment out the code
    // following this section
    WSHttpBinding b = new WSHttpBinding(SecurityMode.Message);
    b.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
    
    EndpointAddress ea = new EndpointAddress("Http://localhost:8036/SecuritySamples/secureCalculator");
    CalculatorClient cc = new CalculatorClient(b, ea);
    cc.Open();
    
    // Now call the service and display the results
    // Call the Add service operation.
    double value1 = 100.00D;
    double value2 = 15.99D;
    double result = cc.Add(value1, value2);
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
    // Closing the client gracefully closes the connection and cleans up resources.
    cc.Close();
    

Utilisation du fichier de configuration

Au lieu de créer la liaison avec le code de procédure, vous pouvez utiliser le code suivant indiqué pour la section Liaisons du fichier de configuration.

Si vous n'avez pas déjà de service défini, consultez Conception et implémentation de services et Configuration des services.

Remarque   Ce code de configuration est utilisé dans les fichiers de configuration du service et du client.

Pour activer la sécurité de transfert sur un service dans un domaine Windows à l'aide de la configuration

  1. Ajoutez un élément <wsHttpBinding> dans la section de l'élément <bindings> du fichier de configuration.

  2. Ajoutez un élément <binding> à l'élément <WSHttpBinding> et affectez à l'attribut configurationName une valeur appropriée à votre application.

  3. Ajoutez un élément <security> et affectez à l'attribut mode la valeur Message.

  4. Ajoutez un élément <message> et affectez à l'attribut clientCredentialType la valeur Windows.

  5. Dans le fichier de configuration du service, remplacez la section <bindings> par le code suivant. Si vous n'avez pas déjà de fichier de configuration de service, consultez Utilisation de liaisons pour configurer des services et des clients.

    <bindings>
      <wsHttpBinding>
       <binding name = "wsHttpBinding_Calculator">
         <security mode="Message">
           <message clientCredentialType="Windows"/>
         </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    

Utilisation de la liaison sur un client

Cette procédure indique comment générer deux fichiers : un proxy qui communique avec le service et un fichier de configuration. Elle décrit également les modifications du programme client, qui est le troisième fichier utilisé sur le client.

Pour utiliser une liaison sur un client avec la configuration

  1. Utilisez l'outil SvcUtil.exe pour générer le code proxy et le fichier de configuration à partir des métadonnées du service. Pour plus d'informations, consultez Comment : créer un client Windows Communication Foundation.

  2. Remplacez la section <Bindings> du fichier de configuration généré par le code de configuration de la section précédente.

  3. Le code de la procédure est inséré au début de la méthode Main du programme client.

  4. Créez une instance de la classe de client générée qui passe le nom de la liaison dans le fichier de configuration comme un paramètre d'entrée.

  5. Appelez la méthode Open, comme illustré dans le code suivant :

  6. Appelez le service et affichez les résultats.

    // 4th Procedure:
    //  Using config instead of the binding-related code
    // In this case, use a binding name from a configuration file generated by the
    // SvcUtil.exe tool to create the client. Omit the binding and endpoint address 
    // because that information is provided by the configuration file.
    
    CalculatorClient cc = new CalculatorClient("ICalculator_Binding");
    cc.Open();
    
    // Now call the service and display the results
    // Call the Add service operation.
    double value1 = 100.00D;
    double value2 = 15.99D;
    double result = cc.Add(value1, value2);
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
    // Closing the client gracefully closes the connection and cleans up resources.
    cc.Close();
    

Exemple

using System;
using System.Collections;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Security.Permissions;

[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
namespace Microsoft.Security.Samples
{
    public class Test
    {
        static void Main()
        {
            Test t = new Test();
            Console.WriteLine("Starting....");
            t.Run();

        }

        private void Run()
        {
            // First procedure:
            // create a WSHttpBinding that uses Windows credentials and message security
            WSHttpBinding myBinding = new WSHttpBinding();
            myBinding.Security.Mode = SecurityMode.Message;
            myBinding.Security.Message.ClientCredentialType =
                MessageCredentialType.Windows;

            // 2nd Procedure:
            // Use the binding in a service
            // 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("https://localhost:8036/SecuritySamples/");

            // Create the ServiceHost and add an endpoint, then start
            // the service.
            ServiceHost myServiceHost =
                new ServiceHost(serviceType, baseAddress);
            myServiceHost.AddServiceEndpoint
                (contractType, myBinding, "secureCalculator");

            //enable metadata
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            myServiceHost.Description.Behaviors.Add(smb);

            myServiceHost.Open();
            Console.WriteLine("Listening");
            Console.WriteLine("Press Enter to close the service");
            Console.ReadLine();
            myServiceHost.Close();
        }
    }

    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double a, double b);
    }

    public class Calculator : ICalculator
    {
        public double Add(double a, double b)
        {
            return a + b;
        }
    }
}

Voir aussi

Tâches

Comment : créer un client Windows Communication Foundation

Référence

WSHttpBinding

Concepts

Outil Service Model Metadata Tool (Svcutil.exe)
Sécurisation de services
Vue d'ensemble de la sécurité