Reporting Services Error : Request for the permission of type ‘system.directoryservices.directoryservicespermission failed

Dans Reporting Services il est possible d’appeler du code VB intégré au rapport ou, encore mieux, externaliser nos fonctions dans une dll custom, pour interroger l’active directory dynamiquement avec le UserId par exemple.
L’appel aux dll privés via les framework .NET 4.0 ou supérieurs semble plus restrictif au niveau sécurité que sur les versions précédentes, car en voulant mettre à jour une vieille dll ce jour nous nous retrouvons avec le message d’erreur suivant :
An error occurred during local report processing.
Request for the permission of type ‘system.directoryservices.directoryservicespermission failed
Après de longues recherches nous avons finalement résolu le problème en combinant les 2 solutions suivantes :
http://technet.microsoft.com/en-us/library/hh389762.aspx
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/6369c60c-3bf4-48a7-9d2e-f87d17099047/image-from-custom-assembly?forum=sqlreportingservices
Avant de commencer
Dans un premier temps, penser à bien copier la dll dans les dossiers suivants :
- Local : ‘dossier installation VS’\Common7\IDE\PrivateAssemblies\
- Server : ‘dossier installation SQL Server’\Reporting Services\ReportServer\bin
- Server bis : ‘dossier installation SQL Server’\Reporting Services\ReportManager\bin
Note : Tout le code ajouté aux fichiers de config sera placé après le bloc :
<CodeGroup class="FirstMatchCodeGroup" version="1" PermissionSetName="Nothing"> <IMembershipCondition class="AllMembershipCondition" version="1" />
Dll en FullTrust
Ensuite, la première partie consiste à forcer l’exécution de notre dll en « FullTrust » dans les fichiers de config :
En local (‘dossier installation VS’\Common7\IDE\PrivateAssemblies\RSPreviewPolicy.config)
<CodeGroup class="UnionCodeGroup" version="1" Name="SecurityExtensionCodeGroup" Description="Code group for the sample security extension" PermissionSetName="FullTrust"> <IMembershipCondition class="UrlMembershipCondition" version="1" Url="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Picasso.dll" /> </CodeGroup>
Sur le server (‘dossier installation SQL Server’\Reporting Services\ReportServer \rssrvpolicy.config)
<CodeGroup class="UnionCodeGroup" version="1" Name="SecurityExtensionCodeGroup" Description="Code group for the sample security extension" PermissionSetName="FullTrust"> <IMembershipCondition class="UrlMembershipCondition" version="1" Url="<dossier installation>\Reporting Services\ReportServer\bin\<MaDLL>.dll" /> </CodeGroup>
Sur le server bis (‘dossier installation SQL Server’\Reporting Services\ReportServer\rsmgrpolicy.config)
<CodeGroup class="UnionCodeGroup" version="1" Name="SecurityExtensionCodeGroup" Description="Code group for the sample security extension" PermissionSetName="FullTrust"> <IMembershipCondition class="UrlMembershipCondition" version="1" Url="<dossier installation>\Reporting Services\ReportManager\bin\<MaDLL>.dll" /> </CodeGroup>
Assembly en FullTrust
Après cette première passe, le rapport s’exécute mais le message d’erreur est remonté au niveau de la dll elle-même. Il nous a donc fallu passer l’assembly ‘system.directoryservices en « fulltrust » également (à la suite du premier bloc dans les 3 fichiers) :
<CodeGroup class="UnionCodeGroup" version="1" Name="SecurityExtensionCodeGroup" Description="Code group for the sample security extension" PermissionSetName="FullTrust"> <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100512C8E872E28569E733BCB123794DAB55111A0570B3B3D4DE3794153DEA5EFB7C3FEA9F2D8236CFF320C4FD0EAD5F677880BF6C181F296C751C5F6E65B04D3834C02F792FEE0FE452915D44AFE74A0C27E0D8E4B8D04EC52A8E281E01FF47E7D694E6C7275A09AFCBFD8CC82705A06B20FD6EF61EBBA6873E29C8C0F2CAEDDA2" /> </CodeGroup>
Après ces 2 étapes notre rapport est de nouveau exécuté correctement.
Il est quand même à noter qu’on perd gros en sécurité, il est donc déconseillé d’utiliser cette modification dans des environnements de production à risque.
“La raison principale est qu’elle donne “tous les droits” a la custom assembly. Dans ce cas, rien n’empêcherait un développeur via cette assembly de supprimer des fichiers importants du système par erreur ou autre” (merci à Philippe Lorieul pour les recherches).
Nous allons tester en attribuant des droits moindres, et je ferais un edit si une solution moins risquée est trouvée.