【问题标题】:SSRS reports for multiple companies/teams多个公司/团队的 SSRS 报告
【发布时间】:2014-05-28 07:42:13
【问题描述】:

我想要一些关于最佳实践的建议。

我正在维护一个 SSRS 报告服务器,现在需要支持多家公司。每家公司都应该只看到自己的数据。并且母公司应该可以看到所有数据,也可以被子公司拆分。

有些报告是相同的,只是查看整体数据的不同子集。

实现这一点的最佳方式是什么,以确保数据只能由适当的公司访问,并且我可以轻松更新报告等,并在以后添加新公司?

我目前正在构建“核心”报告,然后使用公司名称作为隐藏默认参数的链接报告。

另外,我考虑为每个公司创建单独的数据库,并使用主要数据的过滤视图。因此,我将更改 Source,而不是参数。

我知道这是一个悬而未决的问题,但想了解更多有经验的人的利弊,然后再开始讨论。

【问题讨论】:

  • 您打算如何让这些公司访问他们的报告? VPN?
  • 有些在我们的网络中。从外部连接的人将使用 VPN。
  • 您希望子公司有子级别吗? (ABC-Management、ABC-Employee、ABC-peon 等)?
  • 当然。对于主要的子公司,我已经有各种文件夹(管理、财务、营销等)。每个员工都属于相应的 Windows 组,并且只能访问相应的文件夹。

标签: database-design reporting-services


【解决方案1】:

有几种方法可以解决这个问题:

  • 组合数据库并按公司选择
  • 一个数据库中用于分隔公司的架构。为此需要进行一些维护。
  • 每个公司的独立数据库。跨公司的聚合可能很复杂。

假设对于有权访问组合数据库的内部人员而言这不是安全问题,最简单的方法是组合数据库,并在报告中包含逻辑以确保人们只能看到他们被允许访问的公司。

这里有两个问题:

  1. 确定谁在运行报告
  2. 确定可以为哪些公司生成报告

Reporting Services 使用@UserId 全局变量为您解决了第一个问题。

我假设你有一个表格Company,看起来有点像这样:

CompanyId | Name        | ParentCompanyId
----------+-------------+----------------
1         | ABC Inc.    | 
2         | DEF Co.     | 1
3         | GHI Ltd.    | 1
4         | XYZ Corp.   | 

我们需要一种将其映射到他们可以为其运行报告的公司的方法,因此我们创建了一个包含 UserIdCompanyId 字段的表,以将用户映射到他们的公司。

UserId    | Name        | CompanyId
----------+-------------+----------
10        | Alyssa      | 1
20        | David       | 2
30        | Gloria      | 3
40        | Xavier      | 4

所以 Alyssa 可以看到 ABC Inc 及其子公司 DEF Co 和 GHI Ltd,而 David 只能看到 DEF Co,Gloria 只能看到 GHI Ltd,Xavier 只能看到 XYZ Corp。

在您的报告中,您可以根据关系选择数据:

SELECT Invoices.CompanyId, Invoices.Number, Invoices.Date, Invoices.Amount
FROM Invoices
INNER JOIN Companies ON Invoices.CompanyId = Companies.CompanyId
INNER JOIN Users ON Users.UserId = @UserId 
                AND ((Companies.CompanyId = Users.CompanyId) OR (Companies.ParentCompanyId = Users.CompanyId))

好的,这确保用户只能看到与用户关联的公司和子公司的数据:David 只能看到 DEF Co 的发票,而 Alyssa 可以看到 ABC Inc、DEF 的所有发票Co 和 GHI Ltd.

现在,如果 Alyssa 只想见 DEF Co,她需要能够选择该公司。根据此查询创建@CompanyId 参数:

SELECT Companies.CompanyId, Companies.Name
FROM Companies 
INNER JOIN Users ON Users.UserId = @UserId 
                AND ((Companies.CompanyId = Users.CompanyId) OR (Companies.ParentCompanyId = Users.CompanyId))

这显示了用户可以选择的所有公司。设置参数的默认值以从查询中获取其值:

SELECT CompanyId FROM Users WHERE UserId = @UserId

然后我们只需将这个参数添加到我们的查询中:

SELECT Invoices.CompanyId, Invoices.Number, Invoices.Date, Invoices.Amount
FROM Invoices
INNER JOIN Companies ON Invoices.CompanyId = Companies.CompanyId
INNER JOIN Users ON Users.UserId = @UserId 
                AND ((Users.CompanyId = Companies.CompanyId) OR (Users.CompanyId = Companies.ParentCompanyId))
                AND ((@CompanyId = Companies.CompanyId) OR (@CompanyId = Companies.ParentCompanyId))

报告订阅

现在我们开始通过订阅交付报告,而我们围绕使用 @UserId 的策略失败了,因为报告调度程序在其自己的帐户下运行报告,而不是我们想要定位的用户。

让我们创建一个名为User 的隐藏参数并将其设为第一个参数。对于它的可用值属性,创建如下查询:

SELECT UserId, Name
FROM Users
WHERE UserId = @UserId OR @UserId = 'MyDomain\ReportingAccount'

其中MyDomain\ReportingAccount 是您的报告所用的帐户。此查询在实际用户运行报表时仅允许特定用户详细信息,但在报表调度程序运行时允许所有用户。

User 参数的默认值属性设为=User!UserId。当您的报告计划程序运行报告时,对于 User 参数,请提供您要为您发送电子邮件的人的 UserId。

因此,当用户运行报告时,它会选择唯一可能的用户(即他们自己),而当调度程序运行报告时,它会从所有可用用户中选择您想要的用户。作为一个隐藏参数,用户永远不会看到它,所以不知道其中的区别。

如果用户试图变聪明并通过将其作为 URL 中的参数传递来欺骗另一个用户,则它不会是参数可用值的有效选择,因此会失败。

现在只需将上面用于公司选择的查询中的 @UserId 替换为 @User 即可,一切正常。

【讨论】:

  • 谢谢@Chris。我需要稍微消化一下。我为客户支持可以访问的语言做了类似的事情,而且效果很好。一个问题是报告订阅。如果我为其他人创建报告订阅,它将使用我的用户作为当前用户。 (我没有企业版,所以没有数据驱动订阅功能。)所以我需要一个不同版本的电子邮件报告。
  • 另外,只是为了确认一下:这意味着对于每个用户,我需要在服务器上创建一个 Windows 用户,然后还需要一个具有相同用户名的数据库用户。正确的? (如果此人从外部连接,我们的 IT 需要为他创建一个 VPN 用户。)
  • 对于这种方法,他们只需要在您的网络上经过身份验证的 Windows 用户,我假设他们会认为他们正在使用 VPN。您不需要在实际的 SSRS 服务器上创建用户也不要创建数据库用户,但您需要更新 Users 表以包含新用户并指明他们可以访问的公司。显然,您的用户应该无法更新此表。
  • 我有一个关于订阅很长的想法,所以我将它添加到我的答案中。我自己之前没有尝试过这个(我写了我自己的报告调度程序/电子邮件),但它应该可以工作。如果您尝试一下,请告诉我结果如何。
  • 好的,我将与我的 IT 团队讨论有关 Windows 用户的问题。我一直在报告服务器上维护自己的用户。我会检查我们是否可以开始联合 VPN 和报告 Windows 用户。我会看看你的订阅解决方案。谢谢!
【解决方案2】:

我会将安全实施推到数据库的上一层,并通过过滤视图强制访问。通常的技术是构建一个表,列出每个用户可以访问的公司,然后使用 CURRENT_USER 函数过滤具有该表的内部连接的视图。

这是一个更强大的解决方案,因为它不依赖于单独的报告参数设置。它还将支持更多的部署方法,例如SharePoint、Web 应用程序、Excel 等。

有了这个,您的报告管理器部署变得非常简单 - 您可以为所有用户授予对一组文件夹和报告的相同访问权限。

【讨论】:

  • 谢谢@Mike。我看到克里斯以类似的方式更详细地回答了。所以我会在那里继续我的问题/cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多