Partager via


Durable Issued Token Provider

Cet exemple montre comment implémenter un fournisseur de jetons émis client personnalisé. Dans Windows Communication Foundation (WCF), un fournisseur de jetons permet de fournir des informations d'identification à l'infrastructure de sécurité. En général, le fournisseur de jetons examine la cible et publie des informations d'identification appropriées afin que l'infrastructure de sécurité puisse sécuriser le message. WCF est fourni avec un fournisseur de jetons CardSpace. Les fournisseurs de jetons personnalisés sont utiles dans les cas suivants :

  • Si vous disposez d'un magasin d'informations d'identification avec lequel le fournisseur de jetons intégré ne peut pas fonctionner.
  • Si vous souhaitez fournir votre propre mécanisme personnalisé permettant de transformer les informations d'identification entre le moment où l'utilisateur fournit les détails et celui où l'infrastructure cliente WCF les utilise.
  • Si vous générez un jeton personnalisé.

Cet exemple montre comment générer un fournisseur de jetons personnalisé qui met en cache des jetons émis par un service d'émission de jeton de sécurité (STS, Security Token Service).

En résumé, cet exemple montre :

  • la façon dont un client peut être configuré avec un fournisseur de jetons personnalisé ;
  • la façon dont des jetons émis peuvent être mis en cache et fournis à l'infrastructure cliente WCF ;
  • la façon dont le serveur est authentifié par le client à l'aide du certificat X.509 du serveur.

Cet exemple comporte un programme de console client (client.exe), un programme de console de service d'émission de jeton de sécurité (securitytokenservice.exe) et un programme de la console de service (service.exe). Le service implémente un contrat qui définit un modèle de communication demande-réponse. Le contrat est défini par l'interface ICalculator, laquelle expose les opérations mathématiques suivantes : addition, soustraction, multiplication et division. Le client obtient un jeton de sécurité du STS et effectue des demandes synchrones au service pour une opération mathématique donnée, puis le service répond avec le résultat. L'activité du client est visible dans la fenêtre de console.

Aa717045.note(fr-fr,VS.90).gifRemarque :
La procédure d'installation ainsi que les instructions de génération relatives à cet exemple figurent à la fin de cette rubrique.

Cet exemple expose le contrat ICalculator à l'aide de wsFederationHttpBinding Element. La configuration de cette liaison sur le client est présentée dans le code suivant.

<bindings>
  <wsFederationHttpBinding>
    <binding name="ServiceFed" >
      <security mode ="Message">
        <message issuedKeyType ="SymmetricKey" issuedTokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" >
          <issuer address ="https://localhost:8000/sts/windows" binding ="wsHttpBinding" />
        </message>
      </security>
    </binding>
  </wsFederationHttpBinding>
</bindings>

Sur security element of wsFederationHttpBinding, la valeur mode configure le mode de sécurité à utiliser. Dans cet exemple, la sécurité des messages est utilisée ; c'est pourquoi message element of wsFederationHttpBinding est spécifié à l'intérieur de security element of wsFederationHttpBinding. L'élément émetteur de wsFederationHttpBinding à l'intérieur de l'élément de message de wsFederationHttpBinding spécifie l'adresse et la liaison pour le service d'émission de jeton de sécurité qui émet un jeton de sécurité au client afin que celui-ci puisse s'authentifier auprès du service de calculatrice.

La configuration de cette liaison sur le service est présentée dans le code suivant.

<bindings>
  <wsFederationHttpBinding>
    <binding name="ServiceFed" >
      <security mode ="Message">
        <message issuedKeyType ="SymmetricKey" issuedTokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" >
          <issuerMetadata address ="https://localhost:8000/sts/mex" >
            <identity>
              <certificateReference storeLocation ="CurrentUser" 
                                    storeName="TrustedPeople" 
                                    x509FindType ="FindBySubjectDistinguishedName" 
                                    findValue ="CN=STS" />
            </identity>
          </issuerMetadata>
        </message>
      </security>
    </binding>
  </wsFederationHttpBinding>
</bindings>

Sur security element of wsFederationHttpBinding, la valeur mode configure le mode de sécurité à utiliser. Dans cet exemple, la sécurité des messages est utilisée ; c'est pourquoi message element of wsFederationHttpBinding est spécifié à l'intérieur de security element of wsFederationHttpBinding. L'élément issuerMetadata de wsFederationHttpBinding à l'intérieur de l'élément de message de wsFederationHttpBinding spécifie l'adresse et l'identité pour un point de terminaison qui peut être utilisé pour récupérer les métadonnées pour le service d'émission de jeton de sécurité.

Le comportement du service est présenté dans le code suivant.

<behavior name ="ServiceBehaviour" >
  <serviceDebug includeExceptionDetailInFaults ="true"/>
  <serviceMetadata httpGetEnabled ="true"/>
  <serviceCredentials>
    <issuedTokenAuthentication>
      <knownCertificates>
        <add storeLocation ="LocalMachine"
             storeName="TrustedPeople"
             x509FindType="FindBySubjectDistinguishedName"
             findValue="CN=STS" />
      </knownCertificates>
    </issuedTokenAuthentication>
    <serviceCertificate storeLocation ="LocalMachine"
                        storeName ="My"
                        x509FindType ="FindBySubjectDistinguishedName"
                        findValue ="CN=localhost"/>
  </serviceCredentials>
</behavior>

L'élément issuedTokenAuthentication à l'intérieur de l'élément serviceCredentials permet au service de spécifier des contraintes sur les jetons que les clients sont autorisés à présenter pendant l'authentification. Cette configuration spécifie que les jetons signés par un certificat dont le nom du sujet est CN=STS sont acceptés par le service.

SecurityTokenService expose un point de terminaison unique à l'aide du wsHttpBinding standard. Le service d'émission de jeton de sécurité répond pour demander des jetons aux clients et, à la condition que le client s'authentifie à l'aide d'un compte Windows, il émet un jeton qui contient le nom d'utilisateur du client comme revendication dans le jeton émis. Dans le cadre de la création du jeton, le service d'émission de jeton de sécurité le signe à l'aide de la clé privée associée au certificat CN=STS. Par ailleurs, il crée une clé symétrique et la chiffre à l'aide de la clé publique associée au certificat CN=localhost. Lors du retour du jeton au client, le service d'émission de jeton de sécurité retourne également la clé symétrique. Le client présente le jeton émis au service de calculatrice et prouve qu'il connaît la clé symétrique en signant le message à l'aide de celle-ci.

Informations d'identification client personnalisées et fournisseur de jetons personnalisé

Les étapes suivantes indiquent comment développer un fournisseur de jetons personnalisé qui met en cache des jetons émis et l'intégrer avec l'infrastructure de sécurité WCF :

  1. Écrivez un fournisseur de jetons personnalisé.
    L'exemple implémente un fournisseur de jetons personnalisé qui retourne un jeton de sécurité récupéré d'un cache.
    Pour effectuer cette tâche, le fournisseur de jetons personnalisé dérive la classe SecurityTokenProvider et substitue la méthode GetTokenCore. Cette méthode tente d'obtenir un jeton provenant du cache, ou si aucun jeton n'est trouvé dans le cache, elle en récupère un du fournisseur sous-jacent, puis le met en cache. Dans les deux cas, la méthode retourne un SecurityToken.

    protected override SecurityToken GetTokenCore(TimeSpan timeout)
    {
      GenericXmlSecurityToken token;
      if (!this.cache.TryGetToken(target, issuer, out token))
      {
        token = (GenericXmlSecurityToken) this.innerTokenProvider.GetToken(timeout);
        this.cache.AddToken(token, target, issuer);
      }
      return token;
    }
    
  2. Écrivez un gestionnaire de jetons de sécurité personnalisé.
    SecurityTokenManager permet de créer SecurityTokenProvider pour le SecurityTokenRequirement spécifique qui lui est passé dans la méthode CreateSecurityTokenProvider. Le gestionnaire de jetons de sécurité permet également de créer des authentificateurs et des sérialiseurs de jeton, mais ceux-ci ne sont pas traités dans cet exemple. Dans cet exemple, le gestionnaire de jetons de sécurité personnalisé hérite de la classe ClientCredentialsSecurityTokenManager et substitue la méthode CreateSecurityTokenProvider pour retourner le fournisseur de jetons personnalisé lorsque les spécifications du jeton passé indiquent qu'un jeton émis est demandé.

    class DurableIssuedTokenClientCredentialsTokenManager :
     ClientCredentialsSecurityTokenManager
    {
      IssuedTokenCache cache;
    
      public DurableIssuedTokenClientCredentialsTokenManager ( DurableIssuedTokenClientCredentials creds ): base(creds)
      {
        this.cache = creds.IssuedTokenCache;
      }
    
      public override SecurityTokenProvider CreateSecurityTokenProvider ( SecurityTokenRequirement tokenRequirement )
      {
        if (IsIssuedSecurityTokenRequirement(tokenRequirement))
        {
          return new DurableIssuedSecurityTokenProvider ((IssuedSecurityTokenProvider)base.CreateSecurityTokenProvider( tokenRequirement), this.cache);
        }
        Else
        {
          return base.CreateSecurityTokenProvider(tokenRequirement);
        }
      }
    }
    
  3. Écrivez une information d'identification client personnalisée.
    Une classe d'informations d'identification client permet de représenter les informations d'identification qui sont configurées pour le proxy client et crée le gestionnaire de jetons de sécurité utilisé pour obtenir des authentificateurs, des fournisseurs et des sérialiseurs de jeton.

    public class DurableIssuedTokenClientCredentials : ClientCredentials
    {
      IssuedTokenCache cache;
    
      public DurableIssuedTokenClientCredentials() : base()
      {
      }
    
      DurableIssuedTokenClientCredentials ( DurableIssuedTokenClientCredentials other) : base(other)
      {
        this.cache = other.cache;
      }
    
      public IssuedTokenCache IssuedTokenCache
      {
        Get
        {
          return this.cache;
        }
        Set
        {
          this.cache = value;
        }
      }
    
      protected override ClientCredentials CloneCore()
      {
        return new DurableIssuedTokenClientCredentials(this);
      }
    
      public override SecurityTokenManager CreateSecurityTokenManager()
      {
        return new DurableIssuedTokenClientCredentialsTokenManager ((DurableIssuedTokenClientCredentials)this.Clone());
      }
    }
    
  4. Implémentez le cache du jeton. L'exemple d'implémentation utilise une classe de base abstraite par l'intermédiaire de laquelle les consommateurs d'un cache de jeton donné interagissent avec le cache.

    public abstract class IssuedTokenCache
    {
      public abstract void AddToken ( GenericXmlSecurityToken token, EndpointAddress target, EndpointAddress issuer);
      public abstract bool TryGetToken(EndpointAddress target, EndpointAddress issuer, out GenericXmlSecurityToken cachedToken);
    }
    Configure the client to use the custom client credential.
    

    Pour que le client puisse utiliser l'information d'identification client personnalisée, l'exemple supprime la classe d'informations d'identification client par défaut et fournit la nouvelle.

    clientFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
    DurableIssuedTokenClientCredentials durableCreds = new DurableIssuedTokenClientCredentials();
    durableCreds.IssuedTokenCache = cache;
    durableCreds.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
    clientFactory.Endpoint.Behaviors.Add(durableCreds);
    

Exécution de l'exemple

Consultez les instructions suivantes pour exécuter l'exemple. Lorsque vous exécutez l'exemple, la demande de jeton de sécurité s'affiche dans la fenêtre de console du service d'émission de jeton de sécurité. Les demandes et réponses d'opération s'affichent dans les fenêtres de console du client et du service. Appuyez sur ENTER dans l'une ou l'autre de ces fenêtres pour arrêter l'application.

Fichier de commandes d'installation

Le fichier de commandes Setup.cmd inclus avec cet exemple vous permet de configurer le serveur et le service d'émission de jeton de sécurité avec les certificats appropriés pour exécuter une application auto-hébergée. Il crée deux certificats dans le magasin de certificats CurrentUser/TrustedPeople. Le nom du sujet du premier certificat est CN=STS. Ce certificat est utilisé par le service d'émission de jeton de sécurité pour signer les jetons de sécurité qu'il émet au client. Le deuxième a le nom du sujet CN=localhost et est utilisé par le service d'émission de jeton de sécurité pour chiffrer un secret de sorte que le service puisse le déchiffrer. Les éléments suivants fournissent une brève vue d'ensemble des différentes sections des fichiers de commandes afin qu'ils puissent être modifiés pour s'exécuter dans la configuration appropriée.

Pour configurer, générer et exécuter l'exemple

  1. Exécutez le fichier Setup.cmd pour créer les certificats requis.

  2. Pour générer la solution, suivez les instructions indiquées dans Génération des exemples Windows Communication Foundation. Assurez-vous que tous les projets de la solution sont générés (Shared, RSTRSTR, Service, SecurityTokenService et Client).

  3. Assurez-vous que Service.exe et SecurityTokenService.exe s'exécutent.

  4. Exécutez client.exe.

Pour procéder au nettoyage après exécution de l'exemple

  1. Exécutez Cleanup.cmd dans le dossier d'exemples après avoir exécuté l'exemple.

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.