所有权链
当多个数据库对象按顺序互相访问时,该序列便称为“链”。尽管这样的链不会单独存在,但是当 SQL Server 遍历链中的链接时,SQL Server 评估对构成对象的权限时的方式与单独访问对象时不同。这些差异对管理安全性具有重要的影响。
所有权链接通过设置对某个对象(如视图)的权限允许管理对多个对象(如多个表)的访问。所有权链接在允许跳过权限检查的方案中对性能也有少许提高。
如何在链中检查权限
通过链访问对象时,SQL Server 首先将对象的所有者与调用对象的所有者进行比较。调用对象指链中的上一个链接。如果两个对象的所有者相同,则不评估对被引用对象的权限。
所有权链接的示例
在下图中,July2003 视图由 Mary 所拥有。她已经授予 Alex 对该视图的权限。他对此实例中的数据库对象不具有任何其他权限。当 Alex 选择该视图时,会出现什么情况?
Alex 对 July2003 视图执行 SELECT *。SQL Server 检查对该视图的权限并确认 Alex 具有对该视图执行选择的权限。
July2003 视图需要 SalesXZ 视图中的信息。SQL Server 检查 SalesXZ 视图的所有权。因为此视图与调用它的视图具有相同的所有者 (Mary),所以将不检查对 SalesXZ 的权限。返回必需的信息。
SalesXZ 视图需要 InvoicesXZ 视图中的信息。SQL Server 检查 InvoicesXZ 视图的所有权。因为此视图与上一个对象具有相同的所有者,所以将不检查对 InvoicesXZ 的权限。返回必需的信息。到目前为止,序列中的所有项都有一个相同的所有者 (Mary)。这称为“连续所有权链”。
InvoicesXZ 视图需要 AcctAgeXZ 视图中的信息。SQL Server 检查 AcctAgeXZ 视图的所有权。因为此视图的所有者与上一个对象的所有者不同(是 Sam,而不是 Mary),所以将检索有关此视图权限的完整信息。如果 AcctAgeXZ 视图具有允许 Alex 访问的权限,将返回所需的信息。
AcctAgeXZ 视图需要 ExpenseXZ 表中的信息。SQL Server 检查 ExpenseXZ 表的所有权。因为此表的所有者与上一个对象的所有者不同(是 Joe,而不是 Sam),所以将检索有关此表权限的完整信息。如果 ExpenseXZ 表具有允许 Alex 访问的权限,将返回所需的信息。
当 July2003 视图试图从 ProjectionsXZ 表中检索信息时,服务器首先检查 Database 1 和 Database 2 之间是否启用了跨数据库链接。如果已经启用跨数据库链接,服务器将检查 ProjectionsXZ 表的所有权。因为此表与调用视图具有相同的所有者 (Mary),所以将不检查对此表的权限,并且将返回所请求的信息。
跨数据库所有权链接
可以对 SQL Server 进行配置,以允许在单个 SQL Server 实例中的特定数据库之间或所有数据库之间建立所有权链接。默认情况下,跨数据库所有权链接是禁用的,除非由于特殊情况而需要,否则不应该启用它。
潜在威胁
所有权链接在管理对数据库的权限时非常有用,但它假设对象的所有者能够预测到授予对某个安全对象的权限时做出的每个决定的所有后果。在上图中,Mary 拥有 July 2003 视图的大多数基础对象。因为 Mary 具有允许其他用户访问她所拥有的对象的权力,所以 SQL Server 会认为只要 Mary 授予对访问链中第一个视图的权限,即表明她已明确决定共享该视图所引用的视图和表。在现实生活中,这可能不是一个有效的假设。生产数据库比图中所示的数据库要复杂得多,并且控制对它们进行访问的权限几乎不会完全映射到使用它们的组织的管理结构中。
您应该了解,高特权数据库角色的成员可以使用跨数据库所有权链接来访问其自身数据库之外的数据库中的对象。例如,如果在数据库 A 和数据库 B 之间启用了跨数据库所有权链接,则任一数据库的 db_owner 固定数据库角色的成员都可以访问另一数据库。过程很简单:Diane(数据库 A 中 db_owner 角色的成员)在数据库 A 中创建了用户 Stuart。Stuart 已经作为用户存在于数据库 B 中。然后 Diane 在数据库 A 中创建一个对象(由 Stuart 所拥有),该对象调用数据库 B 中 Stuart 所拥有的任何对象。因为调用对象和被调用对象的所有者相同,所以当 Diane 通过她创建的对象访问数据库 B 中的对象时,不会检查她对该对象的权限。