Partager via


Procédure pas à pas : création d'informations d'identification de client et de service personnalisées

Cette rubrique indique comment implémenter des informations d'identification de client et de service personnalisées et comment les utiliser à partir du code d'application.

Classes d'extensibilité d'informations d'identification

Les classes ClientCredentials et ServiceCredentials sont les points d'entrée principaux à l'extensibilité de la sécurité Windows Communication Foundation (WCF). Ces classes d'informations d'identification fournissent les API qui permettent au code d'application de définir des informations d'identification et de convertir les types d'informations d'identification en jetons de sécurité. (Les jetons de sécurité constituent la forme utilisée pour transmettre des informations d'identification à l'intérieur des messages SOAP.) Les responsabilités de ces classes d'informations d'identification peuvent être réparties en deux catégories :

  • Fournir les API pour que les applications définissent des informations d'identification.

  • S'exécuter en tant que fabrique pour les implémentations SecurityTokenManager.

Les deux classes ClientCredentials et ServiceCredentials héritent de la classe SecurityCredentialsManager abstraite qui définit le contrat permettant de retourner SecurityTokenManager.

Pour plus d'informations sur le sujet suivant les classes d'informations d'identification et la manière dont elles s'intègrent dans l'architecture de sécurité WCF, consultez Architecture de sécurité.

Les implémentations par défaut fournies dans WCF prennent en charge les types d'informations d'identification fournis par le système et créent un gestionnaire de jetons de sécurité capable de gérer ces types d'informations d'identification.

Raisons de la personnalisation

La personnalisation des classes d'informations d'identification de service ou de client peut se justifier pour plusieurs raisons. La plus importante est la nécessité de modifier le comportement de sécurité WCF par défaut concernant la gestion des types d'informations d'identification fournis par le système, en particulier pour les motifs suivants :

  • Modifications qu'il n'est pas possible d'effectuer à l'aide d'autres points d'extensibilité.

  • Ajout de nouveaux types d'informations d'identification.

  • Ajout de nouveaux types de jetons de sécurité personnalisés.

Cette rubrique décrit comment implémenter des informations d'identification de client et de service personnalisées et comment les utiliser à partir du code d'application.

Première étape

La création d'une classe d'informations d'identification personnalisée n'est que la première étape, car la personnalisation des informations d'identification a pour objectif de modifier le comportement WCF concernant la fourniture, la sérialisation de jeton de sécurité ou l'authentification des informations d'identification. D'autres rubriques de cette section décrivent comment créer des sérialiseurs et authentificateurs personnalisés. À cet égard, la création de la classe d'informations d'identification personnalisées constitue la première rubrique. Les actions suivantes (création de sérialiseurs et authentificateurs personnalisés) peuvent être effectuées uniquement après la création d'informations d'identification personnalisées. Les autres rubriques basées sur celles-ci sont les suivantes :

Procédures

Pour implémenter des informations d'identification de client personnalisées

  1. Définissez une nouvelle classe dérivée de la classe ClientCredentials.

  2. Facultatif. Ajoutez de nouvelles propriétés ou méthodes pour les nouveaux types d'informations d'identification. Si vous n'ajoutez pas de nouveau type d'informations d'identification, ignorez cette étape. L'exemple suivant ajoute une propriété CreditCardNumber.

  3. Substituez la méthode CreateSecurityTokenManager. Cette méthode est automatiquement appelée par l'infrastructure de sécurité WCF lors de l'utilisation des informations d'identification de client personnalisées. Cette méthode est chargée de créer et de retourner une instance d'une implémentation de la classe SecurityTokenManager.

    ms730868.Important(fr-fr,VS.100).gif Remarque :
    Il est important de noter que la méthode CreateSecurityTokenManager est remplacée pour créer un gestionnaire de jetons de sécurité personnalisé. Le gestionnaire de jetons de sécurité, dérivé de ClientCredentialsSecurityTokenManager, doit retourner un fournisseur de jetons de sécurité personnalisé, dérivé de SecurityTokenProvider, pour créer le jeton de sécurité réel. Si vous ne suivez pas ce modèle pour créer des jetons de sécurité, votre application peut ne pas fonctionner correctement lorsque des objets ChannelFactory sont mis en cache (comportement par défaut des proxys clients WCF), ce qui peut éventuellement provoquer une attaque par élévation de privilège. L'objet personnalisé d'informations d'identification est mis en cache dans le cadre de ChannelFactory. Toutefois, le SecurityTokenManager personnalisé est créé à chaque appel, ce qui limite la menace de sécurité dès l'instant où la logique de création de jeton est placée dans SecurityTokenManager.

  4. Substituez la méthode CloneCore.

    public class MyClientCredentials : ClientCredentials
    {
        string creditCardNumber;
    
        public MyClientCredentials()
        {
            // Perform client credentials initialization.
        }
    
        protected MyClientCredentials(MyClientCredentials other)
            : base(other)
        {
            // Clone fields defined in this class.
            this.creditCardNumber = other.creditCardNumber;
        }
    
        public string CreditCardNumber
        {
            get
            {
                return this.creditCardNumber;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                this.creditCardNumber = value;
            }
        }
    
        public override SecurityTokenManager CreateSecurityTokenManager()
        {
            // Return your implementation of the SecurityTokenManager.
            return new MyClientCredentialsSecurityTokenManager(this);
        }
    
        protected override ClientCredentials CloneCore()
        {
            // Implement the cloning functionality.
            return new MyClientCredentials(this);
        }
    }
    

Pour implémenter un gestionnaire de jetons de sécurité client personnalisé

  1. Définissez une nouvelle classe dérivée de ClientCredentialsSecurityTokenManager.

  2. Facultatif. Substituez la méthode CreateSecurityTokenProvider si une implémentation SecurityTokenProvider personnalisée doit être créée. Pour plus d'informations sur le sujet suivant les fournisseurs de jetons de sécurité personnalisés, consultez Comment : créer un fournisseur de jetons de sécurité personnalisé.

  3. Facultatif. Substituez la méthode CreateSecurityTokenAuthenticator si une implémentation SecurityTokenAuthenticator personnalisée doit être créée. Pour plus d'informations sur le sujet suivant les authentificateurs de jetons de sécurité personnalisés, consultez Comment : créer un authentificateur de jetons de sécurité personnalisé.

  4. Facultatif. Substituez la méthode CreateSecurityTokenSerializer si une SecurityTokenSerializer personnalisée doit être créée. Pour plus d'informations sur le sujet suivant les jetons de sécurité personnalisés et les sérialiseurs de jeton de sécurité personnalisés, consultez Comment : créer un jeton personnalisé.

    internal class MyClientCredentialsSecurityTokenManager : 
        ClientCredentialsSecurityTokenManager
    {
        MyClientCredentials credentials;
    
        public MyClientCredentialsSecurityTokenManager(MyClientCredentials credentials)
            : base(credentials)
        {
            this.credentials = credentials;
        }
    
        public override SecurityTokenProvider CreateSecurityTokenProvider(
            SecurityTokenRequirement tokenRequirement)
        {
            // Return your implementation of the SecurityTokenProvider, if required.
            // This implementation delegates to the base class.
            return base.CreateSecurityTokenProvider(tokenRequirement);
        }
    
        public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(
            SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
        {
            // Return your implementation of the SecurityTokenAuthenticator, if required.
            // This implementation delegates to the base class.
            return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
        }
    
        public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
        {
            // Return your implementation of the SecurityTokenSerializer, if required.
            // This implementation delegates to the base class.
            return base.CreateSecurityTokenSerializer(version);
        }
    }
    

Pour utiliser des informations d'identification de client personnalisées à partir du code de l'application

  1. Créez une instance du client généré qui représente l'interface de service, ou créez une instance de ChannelFactory qui pointe vers un service avec lequel vous souhaitez communiquer.

  2. Supprimez le comportement d'informations d'identification de client fourni par le système de la collection Behaviors, qui est accessible via la propriété Endpoint.

  3. Créez une nouvelle instance d'une classe d'informations d'identification de client personnalisées et ajoutez-la à la collection Behaviors, qui est accessible via la propriété Endpoint.

    // Create a client with the client endpoint configuration.
    CalculatorClient client = new CalculatorClient();
    
    // Remove the ClientCredentials behavior.
    client.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
    
    // Add a custom client credentials instance to the behaviors collection.
    client.ChannelFactory.Endpoint.Behaviors.Add(new MyClientCredentials());
    

La procédure précédente indique comment utiliser des informations d'identification de client à partir du code d'application. Les informations d'identification WCF peuvent également être configurées à l'aide du fichier de configuration de l'application. L'utilisation de la configuration de l'application est souvent préférable à l'encodage effectué de manière irréversible, car elle permet de modifier les paramètres d'application sans qu'il soit nécessaire de modifier la source, de recompiler et de redéployer.

La procédure suivante décrit comment assurer la prise en charge de la configuration des informations d'identification personnalisées.

Création d'un gestionnaire de configuration pour les informations d'identification de client personnalisées

  1. Définissez une nouvelle classe dérivée de ClientCredentialsElement.

  2. Facultatif. Ajoutez des propriétés pour tous les paramètres de configuration supplémentaires que vous souhaitez exposer via la configuration de l'application. L'exemple ci-dessous ajoute une propriété appelée CreditCardNumber.

  3. Substituez la propriété BehaviorType pour retourner le type de la classe d'informations d'identification de client personnalisées créée avec l'élément de configuration.

  4. Substituez la méthode CreateBehavior. La méthode est chargée de créer et de retourner une instance de la classe d'informations d'identification personnalisées en fonction des paramètres chargés à partir du fichier de configuration. Appelez la méthode ApplyConfiguration de base à partir de cette méthode pour récupérer les paramètres d'informations d'identification fournis par le système chargés dans votre instance d'informations d'identification de client personnalisées.

  5. Facultatif. Si vous avez ajouté des propriétés supplémentaires dans l'étape 2, vous devez substituer la propriété Properties pour enregistrer vos paramètres de configuration supplémentaires afin que l'infrastructure de configuration les reconnaisse. Combinez vos propriétés avec celle de la classe de base afin de permettre la configuration des paramètres fournis par le système via cet élément de configuration d'informations d'identification de client personnalisées.

    public class MyClientCredentialsConfigHandler : ClientCredentialsElement
    {
        ConfigurationPropertyCollection properties;
    
        public override Type BehaviorType
        {
            get { return typeof(MyClientCredentials); }
        }
    
        public string CreditCardNumber
        {
            get { return (string)base["creditCardNumber"]; }
            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    value = String.Empty;
                }
                base["creditCardNumber"] = value;
            }
        }
    
        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                if (this.properties == null)
                {
                    ConfigurationPropertyCollection properties = base.Properties;
                    properties.Add(new ConfigurationProperty(
                        "creditCardNumber", 
                        typeof(System.String), 
                        string.Empty,
                        null, 
                        new StringValidator(0, 32, null), 
                        ConfigurationPropertyOptions.None));
                    this.properties = properties;
                }
                return this.properties;
            }
        }
    
        protected override object CreateBehavior()
        {
            MyClientCredentials creds = new MyClientCredentials();
            creds.CreditCardNumber = CreditCardNumber;
            base.ApplyConfiguration(creds);
            return creds;
        }
    }
    

Lorsque vous disposez de la classe de gestionnaire de configuration, vous pouvez l'intégrer dans l'infrastructure de configuration WCF. Cela permet d'utiliser les informations d'identification de client personnalisées dans les éléments de comportement de point de terminaison client, tel qu'indiqué dans la procédure suivante.

Pour inscrire et utiliser un gestionnaire de configuration d'informations d'identification de client personnalisées dans la configuration de l'application

  1. Ajoutez un élément <extensions> et un élément <behaviorExtensions> au fichier de configuration.

  2. Ajoutez un élément <add> à l'élément <behaviorExtensions> et affectez une valeur appropriée à l'attribut name.

  3. Affectez le nom de type complet à l'attribut type. Incluez également le nom d'assembly ainsi que les autres attributs d'assembly.

    <system.serviceModel>
      <extensions>
        <behaviorExtensions>
          <add name="myClientCredentials" type="Microsoft.ServiceModel.Samples.MyClientCredentialsConfigHandler, CustomCredentials, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        </behaviorExtensions>
      </extensions>
    <system.serviceModel>
    
  4. Après avoir inscrit votre gestionnaire de configuration, l'élément d'informations d'identification personnalisées peut être utilisé à l'intérieur du même fichier de configuration au lieu de l'élément <clientCredentials> fourni par le système. Vous pouvez utiliser à la fois les propriétés fournies par le système et les nouvelles propriétés ajoutées à votre implémentation de gestionnaire de configuration. L'exemple suivant définit la valeur d'une propriété personnalisée à l'aide de l'attribut creditCardNumber.

    <behaviors>
      <endpointBehaviors>
        <behavior name="myClientCredentialsBehavior">
          <myClientCredentials creditCardNumber="123-123-123"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    

Pour implémenter des informations d'identification de service personnalisées

  1. Définissez une nouvelle classe dérivée de ServiceCredentials.

  2. Facultatif. Ajoutez de nouvelles propriétés pour fournir des API aux nouvelles valeurs d'informations d'identification ajoutées. Si vous n'ajoutez pas de nouvelle valeur d'informations d'identification, ignorez cette étape. L'exemple suivant ajoute une propriété AdditionalCertificate.

  3. Substituez la méthode CreateSecurityTokenManager. Cette méthode est automatiquement appelée par l'infrastructure WCF lors de l'utilisation des informations d'identification de client personnalisées. La méthode est chargée de créer et de retourner une instance d'une implémentation de la classe SecurityTokenManager (décrite dans la procédure suivante).

  4. Facultatif. Substituez la méthode CloneCore. Cela est uniquement requis lors de l'ajout de nouvelles propriétés ou de nouveaux champs internes à l'implémentation d'informations d'identification de client personnalisées.

    public class MyServiceCredentials : ServiceCredentials
    {
        X509Certificate2 additionalCertificate;
    
        public MyServiceCredentials()
        {
        }
    
        protected MyServiceCredentials(MyServiceCredentials other)
            : base(other)
        {
            this.additionalCertificate = other.additionalCertificate;
        }
    
        public X509Certificate2 AdditionalCertificate
        {
            get
            {
                return this.additionalCertificate;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                this.additionalCertificate = value;
            }
        }
    
        public override SecurityTokenManager CreateSecurityTokenManager()
        {
            return base.CreateSecurityTokenManager();
        }
    
        protected override ServiceCredentials CloneCore()
        {
            return new MyServiceCredentials(this);
        }
    }
    

Pour implémenter un gestionnaire de jetons de sécurité de service personnalisé

  1. Définissez une nouvelle classe dérivée de la classe ServiceCredentialsSecurityTokenManager.

  2. Facultatif. Substituez la méthode CreateSecurityTokenProvider si une implémentation SecurityTokenProvider personnalisée doit être créée. Pour plus d'informations sur le sujet suivant les fournisseurs de jetons de sécurité personnalisés, consultez Comment : créer un fournisseur de jetons de sécurité personnalisé.

  3. Facultatif. Substituez la méthode CreateSecurityTokenAuthenticator si une implémentation SecurityTokenAuthenticator personnalisée doit être créée. Pour plus d'informations sur le sujet suivant les authentificateurs de jetons de sécurité personnalisés, consultez la rubrique Comment : créer un authentificateur de jetons de sécurité personnalisé.

  4. Facultatif. Substituez la méthode CreateSecurityTokenSerializer si une SecurityTokenSerializer personnalisée doit être créée. Pour plus d'informations sur le sujet suivant les jetons de sécurité personnalisés et les sérialiseurs de jeton de sécurité personnalisés, consultez Comment : créer un jeton personnalisé.

    internal class MyServiceCredentialsSecurityTokenManager : 
        ServiceCredentialsSecurityTokenManager
    {
        MyServiceCredentials credentials;
    
        public MyServiceCredentialsSecurityTokenManager(MyServiceCredentials credentials)
            : base(credentials)
        {
            this.credentials = credentials;
        }
    
        public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
        {
            // Return your implementation of SecurityTokenProvider, if required.
            // This implementation delegates to the base class.
            return base.CreateSecurityTokenProvider(tokenRequirement);
        }
    
        public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
        {
            // Return your implementation of SecurityTokenProvider, if required.
            // This implementation delegates to the base class.
            return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
        }
    
        public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
        {
            // Return your implementation of SecurityTokenProvider, if required.
            // This implementation delegates to the base class.
            return base.CreateSecurityTokenSerializer(version);
        }
    }
    

Pour utiliser des informations d'identification de service personnalisées à partir du code de l'application

  1. Créez une instance de ServiceHost.

  2. Supprimez le comportement d'informations d'identification de service fourni par le système de la collection Behaviors.

  3. Créez une instance de la classe d'informations d'identification de service personnalisées et ajoutez-la à la collection Behaviors.

    // Create a service host with a service type.
    ServiceHost serviceHost = new ServiceHost(typeof(Service));
    
    // Remove the default ServiceCredentials behavior.
    serviceHost.Description.Behaviors.Remove<ServiceCredentials>();
    
    // Add a custom service credentials instance to the collection.
    serviceHost.Description.Behaviors.Add(new MyServiceCredentials());
    

Ajoutez la prise en charge de la configuration à l'aide des étapes décrites précédemment dans les procédures « To create a configuration handler for custom client credentials » et « To register and use a custom client credentials configuration handler in the application configuration ». La seule différence réside dans l'utilisation de la classe ServiceCredentialsElement au lieu de la classe ClientCredentialsElement comme classe de base pour le gestionnaire de configuration. L'élément d'informations d'identification de service personnalisées peut ensuite être utilisé partout où l'élément <serviceCredentials> fourni par le système est utilisé.

Voir aussi

Tâches

Comment : créer un fournisseur de jetons de sécurité personnalisé

Référence

ClientCredentials
ServiceCredentials
SecurityCredentialsManager
SecurityTokenManager
ClientCredentialsElement
ServiceCredentialsElement

Concepts

Comment : créer un authentificateur de jetons de sécurité personnalisé
Comment : créer un jeton personnalisé