【问题标题】:SQL Server Permissions on Stored Procs with dynamic SQL使用动态 SQL 对存储过程的 SQL Server 权限
【发布时间】:2011-05-04 03:11:51
【问题描述】:

我有一个具有应用程序角色的数据库。角色成员都属于 Active Directory 中的一个组。我没有授予角色从表中选择的权限,而是授予了角色对它需要调用的所有存储过程的执行权限。

这很好用,除了我的一个存储过程正在构建一些动态 SQL 并调用 sp_executesql。

动态 sql 看起来像这样:

SET @SQL = N'
SELECT * 
FROM dbo.uvView1 
INNER JOIN uvView2 ON uvView1.Id = uvView2.Id'

EXEC sp_executesql @SQL

此角色的用户未能调用存储过程。它给出了以下错误,这是我想的一种预期:

对象“uvView1”、数据库“Foobar”、模式“dbo”的 SELECT 权限被拒绝。

有没有一种方法可以让我的用户成功执行此过程,而无需授予动态 SQL 中所有视图的角色权限?

【问题讨论】:

  • 用户正在访问视图,对吗?我不认为安全关心他们如何访问它。
  • 这是唯一一个失败的过程,它没有在过程上执行权限失败......它特别告诉我它可以从视图中选择......所以我猜它确实以某种方式很重要。
  • 至于为什么会发生这种情况,我发现Dynamic SQL and Ownership Chaining in SQL Server @ mssqltips.com很有用:“当 sp_executesql 或 EXECUTE 语句执行一个字符串时,该字符串将作为它自己的独立批处理执行。... EXECUTE 字符串中引用的安全对象需要权限"

标签: sql sql-server stored-procedures database-security


【解决方案1】:

是的。

在过程中添加一个 EXECUTE AS CALLER 子句,然后对存储过程进行签名,并将所需的权限授予 签名。这是 100% 安全、可靠和防弹的。见Signing Procedures with Certificates

【讨论】:

  • 如果SQL以select开头,则使用数据库触发器监控用户的Sql并拒绝它的解决方案如何?
  • 正如链接文章所说,WITH EXECUTE AS CALLER 是默认值。而且签名过程虽然不愉快,但也不算太复杂,只需要几条SQL命令(CREATE CERTIFICATE+CREATE USER cert$user FROM CERTIFICATE ..,后面跟着ADD SIGNATURE TO @spname BY CERTIFICATE ..GRANT ... TO cert$user
【解决方案2】:

您可以将impersonation 用于具有所需权限的另一个 ID 吗?

SET @SQL = N'
EXECUTE AS USER = ''TrustedUser'';
SELECT * 
FROM dbo.uvView1 
INNER JOIN uvView2 ON uvView1.Id = uvView2.Id'

EXEC sp_executesql @SQL

【讨论】:

  • 好建议,我会看看我是否可以这样做。
  • -1:需要TrustedUser 的IMPERSONATE 权限,这实际上意味着用户拥有受信任用户的所有权限,因为它可以随意冒充他。跨度>
【解决方案3】:

没有。有什么办法可以将其更改为不使用动态 SQL?

【讨论】:

  • 不...不是我所知道的。该查询实际上是在旋转一些数据,并且它所旋转的列是动态的。我的示例并没有真正显示查询的复杂性。
  • 您可能会考虑将所有这些视图放在一个架构中,然后为它们提供架构上的数据读取器访问权限。
猜你喜欢
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
相关资源
最近更新 更多