Utilisation de l’interface ISecurityTrimmer2 avec un type de contenu externe (Business Connectivity Services) 

BCS, Developpement, Sandbox, SharePoint2010

Dans ce billet nous allons voir comment hacher nos résultats de recherche sur des données métiers et y appliquer les règles de sécurité telles qu’elles sont définies dans cette couche métier.

Le moteur de recherche SharePoint (Microsoft Search Server) applique la sécurité sur les résultats remontés par recherche. Il est évident que nous ne voulons pas voir remonter dans la recherche des éléments auxquels l’utilisateur n’a pas accès. Durant le processus d’indexation (crawling), le service associe à chaque document ses ACL (Access Control List), pour permettre de hacher chaque document et de voir si l’utilisateur qui lance la recherche peut voir le document ou pas. Ce processus est plus communément connu sous son nom anglais « security trimming ». Ce mécanisme fonctionne parfaitement bien lorsque les documents sont stockés dans SharePoint.

Qu’en est-il lorsque notre contenu provient d’un système externe via les Business Connectivity Services.

Dans l’API SharePoint, nous trouvons une interface nommée ISecurityTrimmer2, localisée dans la dll Microsoft.Office.Server.Search.Query (j’avoue que le nom de cette interface est assez étrange). Cette interface permet d’implémenter une logique de hachage que nous allons associer à une URL.

Ci-dessous la signature de cette interface :

clip_image001

La méthode clé ici est CheckAccess. Cette méthode prend en paramètres une liste contenant toutes les URL des documents remontés par la recherche. Le deuxième paramètre contient des informations sur le contexte. Enfin, le troisième paramètre nous donne des détails sur l’utilisateur courant. Cette méthode retourne un tableau de bit, contentant des 1 ou des 0 pour spécifier pour chaque document passé en paramètre si l’utilisateur a la permission de le voir (1) ou pas (0).

Dans l’exemple de code ci-dessous, le hachage est très ouvert (voir trop), car la permission de voir le document est donnée à tous les utilisateurs :

clip_image002

Une fois la classe écrite, il ne reste plus qu’à déployer la dll dans le gac des serveurs SharePoint. Il faut ensuite enregistrer ce nouveau trimmer. Pour cela, il faudra exécuter la commande PowerShell suivante :

> $searchapp = Get-SPEnterpriseSearchServiceApplication
 

> new-spenterprisesearchsecuritytrimmer -SearchApplication $a -TypeName "Namespace.Class, Assembly,

Version=x.x.x.x, Culture=neutral, PublicKeyToken=xxxxxx" -RulePath URL -Id 1

 

La première instruction récupère le service de recherche, puis la seconde ajoute un trimmer à ce service. Le trimmer est spécifié dans l’argument TypeName, l’argument RulePath lui prendra la valeur du chemin vers lequel le hachage sera effectué.

Si ce trimmer doit être appliqué sur du contenu provenant d’une source externe, l’URL ici sera quelque chose comme

Bdc3://* 

Cette URL correspond au contenu externe.

 

Ok, jusque-là tout va bien. Nous pouvons ajouter une nouvelle source de contenu, l’indexer, et, ma foi, tout fonctionne.

 

Allons maintenant plus loin, et créons un trimmer pour nos données métiers. Et là, nous allons rencontrer un problème.

 

En effet, une fois le trimmer déployé et ajouté au service de recherche, nous nous rendons compte que l’URL passée à notre méthode CheckAccess de notre trimmer pour chaque document ressemble à :

 

bdc3://myentity/default/00000000%252d0000%252d0000%252d0000%252d000000000000/5286/blah/5288?
     s_id=skaaaaa==uabpac4amaauadiamqawaduanaaxadyangazadia&s_ce=0484840004080g100020o007ufrrvftunn 

 

Que l’on précise une action par défaut, ou une page de profil pour notre entité externe, l’URL précédente sera toujours passée à notre méthode CheckAccess. Mais alors, comment retrouver l’ID de notre entité pour aller vérifier, dans notre couche métier, les permissions de l’utilisateur ?

 

Après avoir fouillé dans les méandres des dll SharePoint depuis l’indispensable .NET Reflector, il s’avère que cette URL complexe contient en fait en paramètre la sérialisation d’une classe qui va contenir l’identifiant de l’instance de l’entité métier. Le code pour récupérer tout ça étant marqué public, il ne me reste plus qu’à l’utiliser dans ma méthode CheckAccess :

 

clip_image004

 

Lignes 34 et 35, une instance de la classe UriParser est créée, cette classe va permettre de nettoyer cette URL complexe (dans le détail, certaines parties seront mises en majuscules). Une fois la chaîne préparée, ligne 37, la valeur du paramètre « s_id » est récupéré. Ce paramètre est en fait la sérialisation de l’instance Identity qui va pouvoir être reconstruite via la méthode statique Deserialize(). Pour finir, ligne 39, les identifiants de l’entité métier seront retrouvés. Il ne reste plus qu’à faire appel au code métier en transmettant ces identifiants et ainsi remplir notre tableau de bit avec les bonnes valeurs.

 

Dans ce billet nous avons vu comment mettre en place un « custom trimmer » pour des données métiers.

 

-Julien


 

 
Posté le 22 Sep 10
Commentaire (1)  |  Url de Trackback  | Lien vers ce message (0) | Marquez ce billet avec:        
 

Liens vers ce message

Commentaires


Gracelyn (2-May-2011)
Thanks for the insight. It binrgs light into the dark!


Nom *:
URL:
Email:
Commentaires:

© 2011 Julien Chomarat - Design based on Blue World