Utilisation du service Banque d’informations sécurisée dans un fournisseur de revendications personnalisées avec SharePoint 2010

J’ai noté récemment un problème inhabituel lors de l’utilisation du service Banque d’informations sécurisée dans un fournisseur de revendications personnalisées sur lequel je travaillais. Il s’agit en fait d’un scénario intéressant car je faisais ce que beaucoup de personnes veulent faire : une augmentation de revendications personnalisées. Je devais me connecter à une source de données distante pour pouvoir obtenir certaines informations supplémentaires sur chaque utilisateur puis les utiliser pour déterminer quelles revendications augmenter ou non.

Au titre de règle générale pour l’utilisation de sources de données dans des fournisseurs de revendications personnalisées, il est important de rappeler que votre assembly de fournisseur de revendications personnalisées sera conservé actif dans la mémoire par le processus STS SharePoint. Cela facilitera grandement la récupération des informations, qu’il s’agisse d’un jeu de données, d’un ensemble d’informations d’identification, etc., de le stocker dans une variable de niveau classe pour le rendre disponible à l’utilisation jusqu’au prochain IISRESET. La limitation importante ici est que certaines ressources de la batterie de serveurs SharePoint ne seront pas disponibles au moment où votre classe de fournisseur de revendications personnalisées sera instanciée, et ceci est la morale de l’histoire d’aujourd’hui.

Dans ce cas particulier, je voulais récupérer des données du service Banque d’informations sécurisée dans le constructeur pour mon fournisseur de revendications personnalisées, puis en faire un certain nombre de choses : dans mon cas, je créais une propriété WindowsIdentity à partir d’un domaine via une approbation monodirectionnelle pour pouvoir l’utiliser pour créer un contexte d’emprunt d’identité disposant des autorisations pour interroger l’annuaire Active Directory distant. Le problème est apparu lorsque j’ai essayé de faire quelque chose avec ma référence au service Banque d’informations sécurisée dans le constructeur : elle dépassait TOUJOURS le délai d’expiration. Quelle que soit la méthode appelée sur le service Banque d’informations sécurisée, elle échouait toujours après 60 secondes avec une erreur de dépassement de délai d’expiration.

La solution consistait simplement à déplacer le code en dehors du constructeur. Un code exactement pareil fonctionnait parfaitement lorsqu’il était appelé depuis ma surcharge de la méthode FillClaimsForEntity. J’ai pu résoudre cela par chance et par essai et erreur : je pense donc que c’est une bonne astuce à partager.

Tant que nous sommes dans ce problème particulier (se connecter à un domaine distant et effectuer un emprunt d’identité), cela vaut probablement la peine d’évoquer une autre question dérivant de ceci, et qui est un autre piège.

Comme décrit plus haut, dans la mesure où votre assembly reste chargé dans le processus STS, vous pouvez conserver  actives »vos variables de niveau classe. Comme je ne voulais évidemment pas me connecter à chaque fois au domaine distant lorsque je voulais l’interroger, j’ai créé une variable de niveau classe pour ma propriété WindowsIdentity. Le schéma était le suivant :

  1. Vérifier si j’ai déjà récupéré les informations d’identification du service Banque d’informations sécurisée
    1. Si ce n’est pas le cas, exécuter le code qui :
      1. Récupère les informations d’identification du service Banque d’informations sécurisée
      2. Utilise l’API LogonUser pour se connecter au domaine distant à l’aide des informations d’identification obtenues auprès du service Banque d’informations sécurisée
      3. Instancier ma variable WindowsIdentity pour qu’elle ait les informations d’identification de l’utilisateur distant
  2. Vérifier si ma variable WindowsIdentity a ou non la valeur null
    1. Si ce n’est pas le cas, exécuter le code qui :
      1. Crée une nouvelle instance d’un contexte WindowsImpersonationContext à partir de WindowsIdentity.Impersonate()
      2. Interroger le domaine distant
      3. Appeler Undo sur mon contexte WindowsImpersonationContext

Ce schéma semble bien fonctionner et être jusqu’à présent aussi performant que souhaité. Voici maintenant le piège : vous NE voulez PAS appeler Impersonate() sur votre instance de WindowsIdentity puis NE PAS appeler après cela Undo sur le contexte WindowsImpersonationContext résultant. Si vous n’annulez pas l’emprunt d’identité, selon mon expérience, le site ne répondra plus. Ajoutez donc votre appel de Undo et tout recommencera à fonctionner.

Ce billet de blog a été traduit de l’anglais. L’article d’origine est disponible à la page Using Secure Store Service in a Custom Claims Provider with SharePoint 2010