模擬使用者或登錄名映射到證書
假設在數據庫中創建了一個證書
create certificate certName with subject = 'subj'; GO
以及映射到此證書的使用者
create user userName from certificate certName; GO
試圖直接冒充該使用者
execute as user = 'userName'; GO
execute as
或在模組的子句中指定使用者create procedure procName with execute as 'userName' as set nocount on; GO
返回錯誤
消息 15517,級別 16,狀態 1 …
無法作為數據庫主體執行,因為主體“userName”不存在,無法模擬此類主體,或者您沒有權限。但是,我無法找到文件(此處和此處)中提到的此限制,其中唯一相關的聲明似乎是
user_name 必須存在於目前數據庫中,並且必須是單例帳戶。user_name 不能是組、角色、證書、密鑰或內置帳戶,例如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。
是否可以模擬映射到證書的使用者(或登錄名)?
不能模擬從證書和非對稱密鑰創建的登錄名和使用者。它們只是一組權限的代理,這些權限將添加到使用相同證書或非對稱密鑰簽名的任何模組中。
此外,冒充這些登錄名和使用者並沒有多大意義,因為:
- 這些代理權限被添加到目前安全上下文(已簽名的執行模組的),而不是替換安全上下文,這就是 Impersonation 所做的。這是一種完全不同的方法,而不僅僅是本質上相同事物的不同機制。
- 模組簽名不適用於臨時查詢。使模組簽名比模擬更安全的部分原因是授予提升權限的人(通過對模組進行簽名以將其與一組額外的權限相關聯)知道程式碼在做什麼,並且一旦給出程式碼提升的權限,它不能被改變來做其他事情,例如做模組簽名的人不會批准的事情。
EXECUTE AS
這是通過在對已簽名模組進行任何更改時刪除簽名以及使用模組文本(包括語句的可選子句CREATE
)來創建簽名的事實來處理的。如果文本更改,則簽名將不匹配。最後,使用從非對稱密鑰和證書創建的登錄名和/或使用者取代了對模擬的需求。
不過,如果要尋找更官方的指標,CREATE USER的 MSDN 頁面指出:
無法驗證的使用者 這些使用者無法登錄 SQL Server 或 SQL 數據庫。
- 沒有登錄的使用者。無法登錄,但可以授予權限。
CREATE USER CustomApp WITHOUT LOGIN;
- 基於證書的使用者。無法登錄但可以被授予權限並且可以簽署模組。
CREATE USER TestProcess FOR CERTIFICATE CarnationProduction50;
- 基於非對稱密鑰的使用者。無法登錄但可以被授予權限並且可以簽署模組。
CREATE User TestProcess FROM ASYMMETRIC KEY PacificSales09;
但是,無法登錄/身份驗證並不意味著“無法模擬”,因為沒有登錄的使用者在該列表中,並且您可以執行
EXECUTE AS USER='{user_without_login}';
.CREATE LOGIN的 MSDN 頁面指出:
從證書或非對稱密鑰創建的登錄僅用於程式碼簽名。它們不能用於連接到 SQL Server。
雖然第二句重複了
CREATE USER
文件所說的內容,但第一句更加具體:它們僅用於程式碼簽名。最後,您在文件中找到的關於EXECUTE AS和EXECUTE AS 子句的限制聲明是正確的,即使它們的措辭令人困惑。他們說(加粗強調):
name必須是單例帳戶,並且不能是組、角色、證書、密鑰或內置帳戶,例如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。
該引用取自
EXECUTE AS
文件,並且EXECUTE AS Clause
問題中引用了文件(幾乎相同的措辭)。雖然這兩個頁面都使用術語“證書”和“密鑰”,但它們實際上分別表示“基於證書的登錄/使用者”和“基於非對稱密鑰的登錄/使用者”。我假設這是基於這樣一個事實,即給定的主體類型列表都可以在sys.server_principals
(對於登錄)和sys.database_principals
(對於使用者)中找到,並且證書和非對稱密鑰都不會在這些系統目錄視圖中列出。