I'm building a SQL Server Reporting Services (SSRS) report. The end user viewing the report can select certain input parameters, in this case locations. The locations the user can select are depending on Active Directory Group Membership, so I'm trying to assert group membership in a custom report function.
(Since the report uses a common datasource connecting to an Oracle database, delegating group membership to the database is not an option)
I've written the following custom code inside a proof-of-concept report:
Function CheckRight(name As String) As String
Try
Dim nameParts = name.Split("/")
Dim user = name(1) + "@" + name(0)
Dim inrole As Boolean = IsInGroup(user, "Domain Users")
Return Iif(inrole, "Yes", "No")
Catch ex As Exception
Return ex.Message
End Try
End Function
Function IsInGroup(user As String, group As String) As Boolean
Dim identity AS System.Security.Principal.WindowsIdentity
identity = New System.Security.Principal.WindowsIdentity(user)
Dim principal = New System.Security.Principal.WindowsPrincipal(identity)
Return principal.IsInRole(group)
End Function
I'm displaying the result in my report using an expression:
=Code.CheckRight(User!UserID)
Instead of displaying 'Yes' or 'No', an error is displayed:
Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
(or in Dutch: 'De aanvraag voor machtiging van type System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is mislukt.')
I'm using Visual Studio 2012, So I'll my PrivateAssemblies is located in C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies.
ANSWER
based on adriano-repetti's answer
I edited PrivateAssemblies\RSPreviewPolicy.config, and got it to work locally:
<NamedPermissionSets>
<!-- added this extra permission set at the bottom: -->
<PermissionSet
class="NamedPermissionSet"
version="1"
Name="PermissionSetForIsInRole"
Description="Permission set that grants rights to WindowsPrincipal.IsInRole.">
<IPermission
class="SecurityPermission"
version="1"
Flags="Execution,ControlPrincipal"/>
</PermissionSet>
</NamedPermissionSets>
<PolicyLevel>
<Codegroup class="FirstMatchCodeGroup" ...>
<CodeGroup
class="FirstMatchCodeGroup"
version="1"
PermissionSetName="Nothing">
<IMembershipCondition
class="AllMembershipCondition"
version="1"
/>
<!-- changed 'Execution' to 'PermissionSetForIsInRole' here: -->
<CodeGroup
class="UnionCodeGroup"
version="1"
PermissionSetName="PermissionSetForIsInRole"
Name="Report_Expressions_Default_Permissions"
Description="This code group grants default permissions for code in report expressions and Code element. ">
<IMembershipCondition
class="StrongNameMembershipCondition"
version="1"
PublicKeyBlob="0024000..."
/>
</CodeGroup>
</CodeGroup>
</PolicyLevel>
SOME NOTES
- Do not try to Assert the right. This results in "Cannot perform CAS Asserts in Security Transparent methods", for the reason described in adriano-repetti's answer.
- It would probably also have been possible to modify the 'execution' permission.
- https://msdn.microsoft.com/en-us/library/ms154466.aspx warns "Code that calls external assemblies or protected resources should be incorporated into a custom assembly for use in reports. Doing so gives you more control over the permissions requested and asserted by your code. You should not make calls to secure methods within the Code element. Doing so requires you to grant FullTrust to the report expression host and grants all custom code full access to the CLR."
- A list of possible security flags can be found at https://msdn.microsoft.com/en-us/library/system.security.permissions.securitypermissionflag(v=vs.110).aspx
- The RSPreviewPolicy.config is used locally only, for previewing locally. On production you need to edit C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services\ReportServer\bin\RSReportServerServices.exe.config. According to https://msdn.microsoft.com/en-us/library/bb630448.aspx - I haven't done this yet.