【问题标题】:Sql Server 2008 schema separation and permissionsSql Server 2008 架构分离和权限
【发布时间】:2011-09-24 11:16:25
【问题描述】:

我目前正在开发一种基础架构,该基础架构将允许我们为多个应用程序提供一个数据库,这些应用程序都共享一组公共实体(表)。每个模式都通过 ORM 映射到一组域对象。

这个想法是有一个管理类型的应用程序来管理一组常见的实体。每个其他应用程序都有自己的实体模式,但此外它只能读取公共集中的实体。由于这些应用程序中的每一个都有自己的数据库登录名和对其指定架构的架构所有权,因此最初这会导致通用架构为所有这些登录名授予只读权限。

或许简单来说,我们有以下三种模式:

  • 常见
  • Schema_A
  • Schema_B

和应用程序:

管理应用:

  • 登录管理员
  • 架构 Common 的所有权
  • 域模型通用

应用 A:

  • 登录A
  • Schema_A 的所有权
  • 只读模式公共所有权
  • 域模型Model_A
  • 域模型通用

应用 B:

  • 登录B
  • Schema_B 的所有权
  • 只读模式 Common
  • 域模型Model_B
  • 域模型通用

上述场景相当简单:为登录 A 和 B 添加对模式 Common 的 SELECT 权限。

但是假设我现在想授予应用程序 A 权限以插入、删除、更新模式 Common 中的特定表。为清楚起见,假设我们有一个名为 Files 的表,任何应用程序都可以将其插入。

我设法完成这项工作的唯一方法是授予登录 A 所有这些架构权限。如果我只授予它对 Common 模式中的表 Files 的权限,它将在运行时被拒绝权限。悬停现在这样做会授予登录 A 对架构中所有表的所有权限 - 这并不是真正可取的。

如何或在何处授予所需的权限以使其仅适用于特定表?

【问题讨论】:

    标签: sql-server sql-server-2008 permissions schema


    【解决方案1】:

    首先:您可以授予单个表的权限,请参阅GRANT Object Permissions 中的第一个示例:

    GRANT SELECT ON OBJECT::Person.Address TO RosaQdM;
    

    因此,您可以简单地将特定表 Common.Files 的 INSERT/UPDATE/DELETE 权限授予 User AUser B(它们是用户,而不是登录,因为您在谈论 database principals)。

    长期以来,推荐的解决方案是使用一组存储过程来控制访问,并授予 EXECUTE 和这些存储过程。见Managing Permissions with Stored Procedures in SQL Server。您可以让您的 ORM 使用这些存储过程而不是原始表访问。这适用于写入操作,但对于允许将任意查询推送到数据库(例如 LINQ)的 ORM 的读取效果不佳,因为存储过程输出结果集不能像直表一样操作。但是由于您的布局无论如何都允许 R/O 访问 Common 模式,因此您可以将其用于所有 SELECT 并且仅将存储过程用于写入操作。

    因此,您可以使用这两种解决方案中的任何一种,或者授予对表的写入权限,或者使用存储过程并授予对它们的 EXECUTE 权限。存储过程添加了一层验证并强制应用程序在使用表时遵守某个 API(例如,他们不能执行DELETE FROM Common.Files 并擦除整个表)。另一方面,直接访问表进行写入更容易在 ORM 中使用。

    【讨论】:

    • 谢谢莱姆斯。我不认为使用存储过程将是一种选择,因为所有业务逻辑重复和委托给数据库。但是,您确实提出了一个很好的观点-也许最好将权限模型应用于应用程序。我直接授予表权限的唯一问题是相同级别的权限(例如 INSERT)不起作用,除非它也在架构级别上授予,这反过来又授予整个架构上的 INSERT。