确定当前正在进行的安全检查 (SQL Server)

Tom*_*m H 5 sql-server security security-context sql-server-2008

我一直最讨厌 MS SQL Server 中的一件事就是安全性的工作方式。如果你有趣地看待服务器,安全上下文会不断切换,而且通常很难(无论如何对我来说)预测或调试。

在今天处理一个问题时,我想,“我希望我可以在代码中添加一行,以显示 SQL Server 在代码运行时使用的安全上下文。” 存在这样的命令吗?例如,SELECT security_context()

更清楚一点...如果我处于存储过程中并且因此受到 SP 所有者的安全上下文的约束,那么我希望看到这一点。如果我在由 sp_executesql 调用的代码中,并且它导致安全性处于 SQL Server 服务帐户的上下文中,那么我希望看到这一点。

至少这样我也许能够弄清楚为什么 SQL Server 认为我不应该访问某些内容。

谢谢!


例子

-- Set up
CREATE USER Test_User WITHOUT LOGIN
CREATE TABLE Test_Security_Context (my_id INT)
INSERT INTO Test_Security_Context VALUES (1)
DENY SELECT ON Test_Security_Context TO Test_User
GO
CREATE PROCEDURE Test_Security_Context_SP
AS
  SELECT SUSER_SNAME()
  SELECT * FROM Test_Security_Context  -- This will return ok
  EXEC('SELECT SUSER_SNAME(); SELECT * FROM Test_Security_Context')  -- SUSER_SNAME() will match above but select fails
GO
GRANT EXECUTE ON Test_Security_Context_SP TO Test_User
GO

-- Switch to the new user
SETUSER 'Test_User'
GO

-- Do the test
EXEC Test_Security_Context_SP
GO

-- Clean up
SETUSER
DROP PROCEDURE Test_Security_Context_SP
DROP TABLE Test_Security_Context
DROP USER Test_User
GO
Run Code Online (Sandbox Code Playgroud)

Rem*_*anu 4

是的,有这样一对视图代表您当前的安全上下文,考虑到 EXECUTE AS 或代码签名等所有细节:

您获得的每一次访问最终都源自这些结果返回中的一行。请注意,某些访问权限是通过硬编码角色成员身份隐式进行的(例如 db_datareader 数据库角色或 sysadmin 服务器角色)。

除此之外:

  • 所有权链与安全上下文无关:您不在 SP 所有者的“上下文”下。所有权链只是指出,对于与当前对象(SP、视图)属于同一所有者的对象,将跳过访问检查。
  • sp_executesql不会以任何方式改变安全上下文