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

时间:2010-08-02 20:55:48

标签: sql-server security sql-server-2008 security-context

我一直讨厌的不仅仅是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

3 个答案:

答案 0 :(得分:4)

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

您获得的每一次访问最终都是从这些结果返回的行中派生出来的。请注意,某些访问是从硬编码角色成员身份隐式的(如db_datareader数据库角色或sysadmin服务器角色)。

其他:

  • 所有权链接与安全上下文无关:您不在SP所有者的“上下文”下。所有权链接只是说明对于与当前对象(SP,View)相同的所有者拥有的对象,将跳过访问检查。
  • sp_executesql 以任何方式更改安全上下文

答案 1 :(得分:1)

不确定这是否是安全上下文的意思,但您可以检索与您的会话相关联的用户,如:

select SYSTEM_USER

这适用于SQL Server登录或WIndows登录。它甚至可以在execute as owner的存储过程中运行。例如,

create procedure dbo.Test
with execute as owner
as
select SYSTEM_USER
go
exec dbo.Test
select SYSTEM_USER

打印:

sa
MyMachine\MyName

如果您正在寻找SQL Server用来代表您执行操作的Windows帐户,您可以尝试从命令运行whoami,如:

EXEC sp_configure 'show advanced options', 1
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE

EXEC master..xp_cmdshell 'whoami'

对我而言,返回nt authority\network service

答案 2 :(得分:1)

我认为您希望使用CURRENT_USER来查看当前的安全上下文。这是一个例子:

SELECT CURRENT_USER AS 'Current User Name';
GO
EXECUTE AS LOGIN = 'junk'
GO
SELECT CURRENT_USER AS 'Current User Name';
GO
REVERT
SELECT CURRENT_USER AS 'Current User Name';
GO

带输出(注意:我是我的SQL Server的管理员)

Current User Name
------------------
dbo

(1 row(s) affected)

Current User Name
------------------
Junk

(1 row(s) affected)

Current User Name
------------------
dbo

(1 row(s) affected)