Le service WCF appelé de manière asynchrone dans ASP.NET utilise un emprunt d’identité incorrect

Cet article vous aide à résoudre le problème où un service Windows Communication Foundation (WCF) appelé de manière asynchrone dans ASP.NET utilise une emprunt d’identité incorrecte.

Version du produit d’origine :   Windows Communication Foundation
Numéro de la base de connaissances initiale :   2890435

Symptômes

Prenons l’exemple du scénario suivant :

  • Un service WCF utilise l’emprunt d’identité et l’authentification Windows.
  • Un client WCF appelle le service de manière asynchrone.
  • Le code client s’exécute sous l’environnement ASP.NET dans Microsoft Internet Information Services (IIS).

Dans ce scénario, vous pouvez rencontrer un problème dans lequel l’opération de service ne s’exécute pas dans le contexte d’emprunt d’identité prévu. Au lieu de cela, vous pouvez trouver l’opération de service en cours d’exécution sous l’identité du processus, comme un pool d’applications IIS.

Notes

  • Lorsque ce problème se produit, aucune exception n’est générée et aucune erreur n’est enregistrée en raison de cette perte du contexte de l’emprunt d’identité.
  • Un exemple de ce type de scénario est une application ASP.NET configurée pour déléguer le contexte d’emprunt d’identité entrant à un service WCF distinct de manière asynchrone.

Cause

Ce problème est dû aux facteurs suivants :

  • Le CLR (Common Language Runtime) de l’hôte supprime délibérément le contexte de l’emprunt d’identité car ASP.NET n’a pas été configuré pour circuler WindowsIdentity entre les opérations asynchrones.
  • Si le code client s’appuie sur l’ouverture automatique et appelle immédiatement des opérations asynchrones sur le proxy client WCF après sa création, le contexte de l’emprunt d’identité risque de ne pas circuler correctement.

Résolution

Pour résoudre ce problème, procédez comme suit :

  1. Configurez ASP.NET pour qu’il circule WindowsIdentity entre les opérations asynchrones. Pour ce faire, assurez-vous que les éléments suivants sont définis dans le fichier aspnet.config :

    <configuration>
        <runtime>
            <legacyImpersonationPolicy enabled="false"/> 
            <alwaysFlowImpersonationPolicy enabled="true"/>
        </runtime>
    </configuration>
    

    Notes

    • Ces paramètres doivent être définis dans le fichier aspnet.config , car ils configurent le CLR qui sera utilisé pour le pool d’applications. Les paramètres définis dans web.config configurent uniquement l’application individuelle, pas le pool d’applications.
    • Assurez-vous de modifier les aspnet.config appropriées pour l’infrastructure installée, comme le %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\Aspnet.config chemin d’accès.
    • Si vous ne pouvez pas modifier le ou les fichiers aspnet.config du serveur, en commençant par IIS 7, vous pouvez associer un aspnet.config personnalisé à chaque pool d’applications. Pour plus d’informations, consultez la section plus d’informations .
  2. Ajoutez un Open() appel explicite au code client. Après avoir créé une instance d’un client WCF, appelez la Open() méthode avant d’appeler des opérations de manière asynchrone. Par exemple :

    // Invoke a service operation asynchronously with impersonation.
    static async void Demo()
    {
       using (CalculatorClient client = new CalculatorClient())
       {
          // Enable the server to impersonate.
          client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
          // Open the client before the first asynchronous request.
          client.Open();
          // Invoke the Add operation asynchronously and display the result.
          double result = await client.AddAsync(1.0, 2.0);
          Console.WriteLine("Add returned {0}", result); client.Close();
       }
    }
    

Plus d’informations

L’ouverture explicite des proxys client lorsqu’ils sont partagés ou utilisés de manière asynchrone est considérée comme une meilleure pratique dans WCF pour plusieurs raisons. Pour plus d’informations, consultez la rubrique meilleure pratique : toujours ouvrir le proxy client WCF de manière explicite lorsqu’il est partagé.

Pour plus d’informations sur un problème similaire qui consiste à utiliser des proxies clients partagés et une communication asynchrone, consultez les opérations de service WCF appelées de manière asynchrone via des proxys de clients partagés à l’aide de l’emprunt d’identité peut utiliser un contexte d’emprunt d’identité incorrect.