2010-08-02 43 views
4

有一件事我一直討厭MS SQL Server中的任何事情都是安全工作的方式。如果你看起來有趣的服務器,並且通常很難(對我來說)預測或調試,安全上下文會不斷切換。確定當前正在進行的安全檢查(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 

回答

4

是的,有這樣一對意見表示當前的安全上下文,考慮到所有細節,如EXECUTE AS或代碼簽名:

您獲得的每個單一訪問權最終都是從這些結果的返回行中派生的。請注意,硬編碼角色成員資格(如db_datareader數據庫角色或sysadmin服務器角色)隱含某些訪問權限。

其他認爲是:

  • 所有權鏈接是不相關的安全上下文:你是不是對SP所有者的「語境」下。所有權鏈接簡單地說,對於同一所有者擁有的對象與當前對象(SP,View)跳過訪問檢查。
  • sp_executesql以任何方式更改安全上下文
+0

+ 1哇!一個問題:爲什麼'builtin \ administrators'的login_token說'只拒絕'?我原以爲這是我的大部分撥款的原因! – Andomar 2010-08-03 04:49:25

+1

@Andomar:我認爲是Vista LUA,它修改了管理員令牌但我不確定 – 2010-08-03 05:52:40

+0

也許我的角色很糟糕,我在尋找的是「這就是爲什麼你沒有權限」和「這就是爲什麼你有權限」米可能會問太多,但我知道,我並不孤單,試圖解開這些類型的安全漏洞,特別是當涉及到跨數據庫訪問,動態SQL等。 – 2010-08-03 14:53:52

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 

如果你正在尋找的Windows帳戶SQL Server使用做代表你的東西,你可以嘗試從命令一樣運行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

+0

雖然SUSER_SNAME()與會話關聯的用戶,不會仍然是有效的,當你在一個存儲過程是(使用SP所有者的安全上下文)或者當您使用像EXEC(@cmd)這樣的動態SQL時。更不用說所有權鏈接的整個混亂。 :( – 2010-08-02 21:13:57

+1

@Tom H:'suser_sname()'和'SYSTEM_USER'對於存儲過程似乎都能很好地工作(例子中添加了答案)。也許你可以發佈一個失敗的例子嗎? – Andomar 2010-08-02 21:21:12

+0

我已經添加了一個使用動態SQL在兩個地方都會返回相同的SUSER_SNAME(),但是在其中一個選擇失敗,而另一個則成功。 – 2010-08-03 14:46:05

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服務器上管理員這個)

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

(1 row(s) affected) 

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

(1 row(s) affected) 

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

(1 row(s) affected) 
+0

這與Andomar的解決方案存在相同的問題請參見上面添加的示例 – 2010-08-03 14:47:48

相關問題