什么可能导致 SQL Server 一开始拒绝执行 SP,但稍后允许它不更改权限?

Ron*_*ldo 7 sql-server permissions errors sql-server-2014

用户(Windows 登录)刚刚抱怨他被拒绝执行程序。我去检查并确认他有执行它的权限。我没有改变任何东西(现在我是唯一一个拥有管理员权限的人,如果需要的话),在两次尝试失败后,他尝试第三次运行 SP 并且成功了。

我将 XE 配置为捕获错误消息,它捕获了错误代码 229 的两倍:

对象“storedProcedureName”、数据库“databaseName”、架构“schemaName”的 EXECUTE 权限被拒绝。

是否存在预期这种行为的任何情况?


Microsoft SQL Server 2014 (SP3-CU-GDR) (KB4535288) - 12.0.6372.1 (X64)

Jos*_*ell 19

如果同时将 Windows 用户帐户添加到 Active Directory (AD) 组,并且该 AD 组有权运行该过程,则可能会创建这种情况,即用户获得对过程的访问权限,而 SQL Server 中没有任何更改.

还要让网络管理员检查用户是否注销并再次登录。组成员身份仅在登录时分配,因此如果用户被添加到组并且尚未注销,他的令牌中就不会具有该组成员身份。- 斯波里

相关问答:如何在 SQL Server 2008 中分配整个 Active Directory 组的安全访问权限?


Han*_*non 14

另一个可能的根本原因是对存储过程定义如何终止的误解。以这个为例:

CREATE OR ALTER PROCEDURE dbo.MyTestProc
AS
BEGIN
    SELECT result = 1;
END
GRANT EXECUTE ON dbo.MyTestProc TO [SomeUser];
Run Code Online (Sandbox Code Playgroud)

此处的目的是定义过程,然后为其授予权限。

但是,第一次执行该批处理时,权限dbo.MyTestProc不会改变。第一次存储的过程本身执行,通过EXEC dbo.MyTestProc,权限将被授予允许[SomeUser]执行PROC。

创建该 proc 并为其授予权限的更正批处理将是:

CREATE OR ALTER PROCEDURE dbo.MyTestProc
AS
BEGIN
    SELECT result = 1;
END
GO
GRANT EXECUTE ON dbo.MyTestProc TO [SomeUser];
Run Code Online (Sandbox Code Playgroud)

GO过程定义,和之间的GRANT表态意味着当您执行批处理,程序将创建并授权将立即生效。

如果 proc 定义不正确,如上所示,用户可能无法执行它。如果您随后以系统管理员身份执行该 proc,那么第一次执行它就会授予他们访问权限。

  • 谢谢,马克斯·弗农。真的很高兴知道它,但是很容易验证这不是这里的情况,因为我测试了创建一个像你提到的那样的过程 - 授权保留在过程定义中。但是,我从错误中生成了该过程的脚本,并且 DDL 没有授权。尽管如此,这肯定是另一种预期 OP 行为的情况。 (2认同)

Gre*_*ker 11

也许用户有一个无效的 Kerberos 票证(例如过期),这导致了两个“拒绝访问”错误。在此之后的某个时间点,用户的工作站联系 DC 并更新票证,允许用户第三次执行该过程。

  • 这是一个非常有趣的可能性;我注意到,由于我一直在家工作并通过 VPN 登录到公司网络,因此在我尝试访问 SQL Server 的前几次尝试访问 SQL Server 时,有时会在 SQL Server Management Studio 中遇到“拒绝访问”错误(这已经发生了)在不止一台服务器上,不止一次),但在第三次或第四次尝试登录成功。现在我想一想,这只是在我晚上让笔记本电脑入睡并在早上重新连接到超时 VPN 会话后才发生的。有什么要看的。 (4认同)
  • 您可以使用带有清除选项的命令行实用程序 klist.exe 来近似解决此问题,这将删除存储在当前会话中的所有 kerberos 票证。您需要先退出 SSMS,然后从命令行运行 `klist purge`,然后立即尝试连接 ssms。通过 klist 清除票证意味着您的工作站会话必须联系域控制器以获取新的 kerberos 票证。如果 DC 需要一段时间来响应,则可能会导致拒绝访问错误。 (2认同)

Tib*_*szi 8

Josh 的回答相关:另一种选择可能是此人是 AD 组的成员,该组有明确DENY的操作。然后这个人就被从AD组中删除了DENY

我说的是数据库中的用户。指向登录的用户,其中该登录指向一个 AD 组,即拒绝可以作为用户完成,最后指向该 AD 组。您的人可能是该 AD 组的成员。与 Josh 的示例几乎相同,但相反。

不像乔希的例子那么可能,但有道理。