Security 基于Reporting Services中的参数控制报表权限
假设我们有一个大部门的报告,名为SalesSummary。该部门针对每种产品都有许多较小的团队。人们应该能够看到关于自己产品的信息,而不是其他团队的产品。我们还为每个团队提供了一个域组 复制每个团队的SalesSummary报告并设置权限不是最好的选择,因为我们有很多产品。我想在RS上使用类似于下面的代码,但它不起作用。显然,RS上默认禁用System.Security.Principal.WindowsPrincipalSecurity 基于Reporting Services中的参数控制报表权限,security,reporting-services,Security,Reporting Services,假设我们有一个大部门的报告,名为SalesSummary。该部门针对每种产品都有许多较小的团队。人们应该能够看到关于自己产品的信息,而不是其他团队的产品。我们还为每个团队提供了一个域组 复制每个团队的SalesSummary报告并设置权限不是最好的选择,因为我们有很多产品。我想在RS上使用类似于下面的代码,但它不起作用。显然,RS上默认禁用System.Security.Principal.WindowsPrincipal Public Function isPermitted() As Boo
Public Function isPermitted() As Boolean
Dim Principal As New System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent())
If (Principal.IsInRole("group_prod")) Then
Return true
Else
Return false
End If
End Function
我还认为我可以将用户ID从RS发送到SQL server,在我的SP中,我可以使用类似于下面的代码来查询active directory。由于安全限制,这也不起作用
SELECT
*
FROM OPENQUERY(ADSI,'SELECT cn, ADsPath FROM ''LDAP://DC=Fabricam,DC=com'' WHERE objectCategory=''group''')
有没有更简单的方法来实现这个目标
谢谢你的帮助 您建议的第一个选项(使用嵌入式代码识别执行用户)将不可靠。SSRS代码不一定作为访问报告的用户执行,并且可能无法访问该用户的凭据,例如在运行订阅时 第二种方法可行,但需要SQL server服务帐户具有相应的权限才能查询Active Directory
另一种方法是在SQL表中维护组成员资格或用户权限的副本。此表可以手动更新,也可以通过自动化流程更新。然后,您可以轻松地将其合并到可用参数和核心数据查询中。因此,我最终得到以下代码:
PrincipalContext domain = new PrincipalContext(ContextType.Domain, "AD");
UserPrincipal user = UserPrincipal.FindByIdentity(domain, identityName);
//// if found - grab its groups
if (user != null)
{
PrincipalSearchResult<Principal> _groups = null;
int tries = 0;
//We have this while because GetGroups sometimes fails! Specially if you don't
// mention the domain in PrincipalContext
while (true)
{
try
{
_groups = user.GetGroups();
break;
}
catch (Exception ex)
{
logger.Debug("get groups failed", ex);
if (tries > 5) throw;
tries++;
}
}
// iterate over all groups, just gets groups related to this app
foreach (Principal p in _groups)
{
// make sure to add only group principals
if (p is GroupPrincipal)
{
if (p.Name.StartsWith(GROUP_IDENTIFIER))
{
this.groups.Add((GroupPrincipal)p);
this.groupNames.Add(p.Name);
}
}
}
}
PrincipalContext域=新PrincipalContext(ContextType.domain,“AD”);
UserPrincipal user=UserPrincipal.FindByIdentity(域,标识名);
////如果找到-抓取它的组
如果(用户!=null)
{
PrincipalSearchResult_groups=null;
int=0;
//我们有这段时间,因为GetGroups有时会失败!特别是如果您没有这样做的话
//在PrincipalContext中提到域
while(true)
{
尝试
{
_groups=user.GetGroups();
打破
}
捕获(例外情况除外)
{
调试(“获取组失败”,例如);
如果(尝试次数>5次)投掷;
尝试++;
}
}
//迭代所有组,只获取与此应用程序相关的组
foreach(p在_群中的主体)
{
//确保只添加组主体
if(p是GroupPrincipal)
{
if(p.Name.StartsWith(组标识符))
{
this.groups.Add((GroupPrincipal)p);
this.groupNames.Add(p.Name);
}
}
}
}
现在,您已经有了相关组的列表,您可以检查该列表以授权用户 我遇到了类似的情况,我打算使用ReportViewer控件,让我的应用程序控制对报表服务器的远程访问,并传入离散参数。它如何与导出报表一起工作?它是否通过ReportViewer导出报告或将URL发送到RS。我不希望人们通过构建querystring或更改post变量来进行黑客攻击。当然ReportViewer也会进行导出。用户甚至无法访问报表服务器。我只需要确保离散参数是安全的,并且在参数提示阶段不能被用户修改。@dotjoe我想我会试试你的方法。请将您的评论作为答案,以便我可以接受。我们已经在数据库中保留了用户组及其权限,但我们不想保留用户名。这真的很难维持。问题在于找出用户所属的组。感谢您对SSR的评论,它并不总是运行代码。