检查 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>
一些注意事项
- 不要试图主张权利。由于 adriano-repetti 的回答中描述的原因,这导致 "Cannot perform CAS Asserts in Security Transparent methods"。
- 可能也可以修改 'execution' 权限。
- https://msdn.microsoft.com/en-us/library/ms154466.aspx 警告 "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."
- 可在 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。根据 https://msdn.microsoft.com/en-us/library/bb630448.aspx - 我还没有这样做。
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.
我正在构建 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>
一些注意事项
- 不要试图主张权利。由于 adriano-repetti 的回答中描述的原因,这导致 "Cannot perform CAS Asserts in Security Transparent methods"。
- 可能也可以修改 'execution' 权限。
- https://msdn.microsoft.com/en-us/library/ms154466.aspx 警告 "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."
- 可在 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。根据 https://msdn.microsoft.com/en-us/library/bb630448.aspx - 我还没有这样做。
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.