我有一个由SQL用户执行的存储过程(称为client.UpdateClient
)(称为MyWCFServicesUser
.
MyWCFServicesUser
对数据库具有数据读取器和数据写入器权限。它还具有存储过程的执行权限(但没有其他权限)。
存储过程将使用SET IDENITY_INSERT client.Client ON
在client.Client
中插入一行。
当我使用集成安全性(我是sa
)运行此存储过程(来自SSMS)时,一切都正常。
当我以MyWCFServicesUser
(来自SSMS)的身份运行它时,它失败了,并出现以下错误:
消息1088,级别16,状态11,过程更新客户端,第33行
找不到对象"client.client",因为它不存在或您没有权限。
我通常将所有存储过程和表都放在默认(dbo)架构中,但这次我尝试不使用dbo。
这就是我没有权限的原因吗?我是否需要以某种方式提升存储过程?还是用户?或者以某种方式更改模式?
我被难住了。。。
原来SET IDENTITY_INSERT需要用户更改权限。
解决存储过程中权限要求的正确方法是使用代码签名。通过这种方式,您可以将所需的权限(即ALTER TABLE
)授予过程,而不授予用户,并且您只需要将过程(或架构)的EXECUTE授予用户。其优点是,您的低权限用户只能调用该过程,并根据该过程的控制执行任何需要提升权限的操作(即设置identity_insert)。如果您被直接授予用户所需的权限,他/她可以将其用于所述权限允许的任何操作(例如添加列、删除约束等)。该链接有几个示例。
话虽如此,我必须指出,您的问题是关于SET IDENTITY_INSERT
的,这是一个通常用于一次性数据加载的特殊设置。事实上,您是从一个看似例行的CRUD UpdateClient
过程中设置的,这有点像代码气味。
重要的是谁是您提到的对象的所有者。它们有可能是由不同的用户创建的吗?也许sa是表的所有者,而MyWCFServicesUser拥有proc?
请参阅有关所有权链的链接http://msdn.microsoft.com/en-us/library/ms188676.aspx它可能有助于您的调查