在SSRS报告自定义代码中检查“获取目录组成员资格”表单

时间:2016-01-18 08:16:36

标签: .net reporting-services ssrs-2012

我正在构建SQL Server Reporting Services(SSRS)报告。查看报告的最终用户可以选择某些输入参数,在这种情况下是位置。用户可以选择的位置取决于Active Directory组成员身份,因此我尝试在自定义报告功能中声明组成员身份。

(由于报告使用连接到Oracle数据库的公共数据源,因此不能将组成员身份委派给数据库)

我在概念验证报告中写了以下自定义代码:

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

我使用表达式在报告中显示结果:

=Code.CheckRight(User!UserID)

不显示“是”或“否”,而是显示错误:

请求获得类型'System.Security.Permissions.SecurityPermission,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'的权限失败。

(或荷兰语:'de aanvraag voor machtiging van type System.Security.Permissions.SecurityPermission, mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089 mislukt。')

我正在使用Visual Studio 2012,所以我的 PrivateAssemblies 位于C:\ Program Files(x86)\ Microsoft Visual Studio 12.0 \ Common7 \ IDE \ PrivateAssemblies。

ANSWER

基于adriano-repetti的回答

我编辑了 PrivateAssemblies \ RSPreviewPolicy.config,并让它在本地工作:

<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>

一些注意事项

  • 不要试图断言权利。由于adriano-repetti的答案中描述的原因,这导致“无法在安全透明方法中执行CAS断言”。
  • 可能还可以修改'执行'权限。
  • https://msdn.microsoft.com/en-us/library/ms154466.aspx警告“调用外部程序集或受保护资源的代码应合并到自定义程序集中以便在报告中使用。这样做可以让您更好地控制代码请求和声明的权限。您不应该调用Code元素中的安​​全方法。这样做需要您将FullTrust授予报表表达式主机,并授予所有自定义代码对CLR的完全访问权。“
  • 可以在https://msdn.microsoft.com/en-us/library/system.security.permissions.securitypermissionflag(v=vs.110).aspx
  • 找到可能的安全标记列表
  • RSPreviewPolicy.config仅在本地使用,用于本地预览。在生产时,您需要编辑C:\ Program Files \ Microsoft SQL Server \ MSRS11.MSSQLSERVER \ Reporting Services \ ReportServer \ bin \ RSReportServerServices.exe.config。根据{{​​3}} - 我还没有这样做。

1 个答案:

答案 0 :(得分:0)

WindowsPrincipal.IsInRole()方法需要SecurityPermissionFlag.ControlPrincipal权限,默认情况下,该权限不会授予报告中的自定义代码。

您可以更改配置以包含named permission-set(有关此问题的详细信息,请参阅该文章):

<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>

请勿忘记将此权限集与权限<CodeGroup>(在您的情况下为Report_Expressions_Default_Permissions)和正确的配置文件相关联。

这会影响您的整体安全吗?当然是的,那么您应该只授予所需权限,并且仅授予需要它们的报告。如果为SSRS报告正确配置了安全性,那么这应该不是问题。

关于您的第二个版本它不起作用,因为透明代码(在SSRS中执行的代码)透明到安全性并且它无法断言/直接更改安全性(另请参阅规则 CA2140:透明代码不得引用安全关键项。)

  

透明性是一种强制机制,它将作为应用程序一部分运行的代码与作为基础结构一部分运行的代码分开。透明度在可以执行特权事务(关键代码)的代码(例如调用本机代码)和不能代码(透明代码)之间划清界限。透明代码可以在其运行的权限集的边界内执行命令,但不能执行,派生或包含关键代码。