SharePoint : RunWithElevatedPrivileges, attention à la portée des variables

Lorsque votre code SharePoint doit exécuter des actions pour lesquelles l’utilisateur n’a pas les droits, vous pouvez utiliser la méthode SPSecurity.RunWithElevatedPrivileges. Cette dernière attend un delegate en argument. Le delegate est alors appelé sans restriction d’autorisation, au lieu de brider les appels aux autorisations de l’utilisateur connecté. Bien entendu à utiliser avec précaution, pensez à bien verrouiller la portée de votre code.

Toutefois, l’utilisation de cette méthode peut amener quelques surprise. Par exemple, j’ai sur un de mes site SharePoint un groupe dont l’option « Qui peut consulter l’appartenance au groupe? » est positionnée sur « Membres du groupe ». Ainsi, un utilisateur non administrateur ne peut consulter les membres de ce groupe. Si dans votre code, vous devez découvrir les membres de ce groupe (on peut imaginer un scénario ou on a un groupe de personne responsable d’une étape de workflow, sans que les utilisateurs les connaissent), vous écrirez naturellement le code suivant :

Si vous exécutez ce code avec votre compte « administrateur » de la machine, aucun problème. Arrive les tests, avec un compte sans droit particulier (vous testez bien vos développements avec un utilisateur simple, n’est ce pas ?), vous obtiendrez une erreur (pour SharePoint 2010) :

 

Cette erreur est suivie d’une redirection automatique vers la page « Access Denied ».

Si vous observez la pile, vous verrez l’appel à une méthode « HandleAccessDenied ». Surprise! Vous pensiez avoir tous les droits, et il se trouve que non.

Remarque : pour SharePoint 2007, le problème est similaire, mais le message d’erreur est différent (un horrible HRESULT ave E_ACCESS_DENIED à l’ancienne). La résolution est similaire.

L’origine du problème se trouve dans la ligne suivante :

En effet, le code utilise ici le contexte de l’utilisateur connecté pour récupérer le groupe. Ce contexte a déjà été créé, et ne dispose que des autorisations de l’utilisateur connecté. Même si le code s’exécute dans un mode élevé, les autorisations sont déjà positionnées.

Pour contourner ce problème, il suffit de créer une nouvelle instance de la classe SPSite à l’intérieur du code élevé. Le code précédent mis à jour est alors le suivant :

Ce code cette fois ci s’exécute sans aucun problème. La variable tempsite est créée facilement à partir du contexte. Tous les appels suivants sont faits à partir de cette variable.

Notez au passage l’utilisation du bloc using sur la variable de type SPSite pour éviter les problèmes de fuite mémoire.

Conclusion :

Cet article vous aura permis, je l’espère, de voir comment on peut se faire avoir avec la méthode RunWithElevatedPrivileges, mais aussi de comprendre l’origine du problème et la solution pour le corriger.

Rating 3.50 out of 5
[?]