检查 SSRS 报告自定义代码中的 Active Directory 组成员身份表单

Check Acive Directory Group Membership form within SSRS Report Custom Code

我正在构建 SQL 服务器报告服务 (SSRS) 报告。查看报告的最终用户可以 select 某些输入参数,在本例中为位置。用户可以 select 的位置取决于 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)

而不是显示'Yes'或'No',而是显示错误:

请求类型 '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 不正确。')

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


回答

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

一些注意事项


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 中执行的代码)是 透明 安全并且它可以't assert/change 直接安全(另请参阅规则 CA2140:透明代码不得引用安全关键项。)

Transparency is an enforcement mechanism that separates code that runs as part of the application from code that runs as part of the infrastructure. Transparency draws a barrier between code that can do privileged things (critical code), such as calling native code, and code that cannot (transparent code). Transparent code can execute commands within the bounds of the permission set it is operating in, but cannot execute, derive from, or contain critical code.