我正在使用Sql Server 2008并且有一个在内部使用sp_executesql的proc。通过ASP.NET执行proc时,我一直收到以下错误:
对象'MyTable',数据库'MyDatabase',架构'dbo'上的SELECT权限被拒绝。
我已经对此进行了大量研究,大多数人都指出我需要在动态查询读取的基础表上授予select权限。好吧,我已经做到了这一点,但它似乎仍然无效:
select object_name(major_id) as object,
user_name(grantee_principal_id) as grantee,
user_name(grantor_principal_id) as grantor,
permission_name,
state_desc
from sys.database_permissions
where major_id = object_id('User') and
class = 1
Results: MyTable public dbo SELECT GRANT MyTable guest dbo SELECT GRANT MyTable myuser dbo SELECT GRANT MyTable NT AUTHORITY\NETWORK SERVICE dbo SELECT GRANT
正如你所看到的,我试图在基础表上授予select,这已经过分了。我甚至重新编写了我的proc,以便它只在动态sql中引用MyTable。我甚至已经授予了所有上述用户对proc的“执行”权限......没有运气。
上面的“myuser”是web.config中我的connectionstring中的用户名。
我在这里错过了什么吗?
谢谢! 戴夫
答案 0 :(得分:5)
我明白了。将其发布给遇到此问题的其他任何人。
1)首先,我注意到我的dbo用户没有与之关联的登录名。您可以通过右键单击dbo用户的Security / Users文件夹中的dbo用户并单击Properties来查看。在灰色区域中,您应该是用户名(dbo)和登录名(sa)。我认为这通常发生在您还原数据库或某些事情时(不确定)。无论如何,如果你没有看到登录名,只需在数据库中运行问题:
sp_changedbowner'sa'
这只会使dbo成为数据库的所有者(或类似的东西)。我发现这个的原因是因为我尝试通过这个gui接口保存一些权限,例如“db_datareader”,“db_datawriter”,但是抛出了一个错误,说明需要登录名。我认为dbo应该检查db_owner(我的确如此),我认为无论如何这都胜过其他人。
2)为了让我的proc工作,我必须在proc结束时添加“with execute as owner”。我以前试过这个,但是因为我的第一个问题#1而认为它不起作用。 Proc通常在proc的所有者下运行,但在procs中不是动态sql。它们在用户执行proc的上下文中运行。对我来说这很奇怪,因为我认为我需要在动态sql(我试过)中添加它,但它需要在proc本身(去图?)
3)运行此脚本也可能不会受到伤害:
将'MyTable'上的选择授予'MyUser'
表示动态sql中使用的每个表。
希望这会有所帮助......
这里引用了同样的问题:
http://kbalertz.com/301299/Security-Context-Dynamic-Statements-Inside-Stored-Procedure.aspx
答案 1 :(得分:0)
对我有帮助的是:
在SQL Management Studio中,右键单击存储过程并选择“属性”,然后在“权限”页面上向相关用户授予权限。相关用户取决于您的SQL连接字符串:如果您使用的是Windows身份验证,那么它是Windows用户(如果配置了可能是ASPNET);否则它是您在连接字符串中指定的SQL用户。您需要授予的权限是执行权限。