SqlContext 物件
適用於:SQL Server
當您呼叫程式或函式、在 Common Language Runtime (CLR) 使用者定義型別上呼叫方法,或當您的動作引發任何 .NET Framework 語言中定義的觸發程式時,請在伺服器中叫用 Managed 程式代碼。 由於執行此程式代碼是要求作為用戶連線的一部分,因此需要從伺服器中執行之程式代碼存取呼叫端的內容。 此外,只有在呼叫端的內容下執行時,特定數據存取作業才有效。 例如,存取觸發程式作業中使用的插入和刪除虛擬數據表,只有在呼叫端的內容下才有效。
呼叫者的內容會在 SqlContext
物件中抽象化。 如需詳細資訊,請參閱 Microsoft.SqlServer.Server.SqlContext。
SqlContext
提供下列元件的存取權。
元件 | 描述 |
---|---|
SqlPipe |
此物件代表 管道 結果流向用戶端。 如需詳細資訊,請參閱 |
SqlTriggerContext |
此物件只能從 CLR 觸發程式內擷取。 它提供導致觸發程式引發之作業的相關信息,以及已更新之數據行的對應。 如需詳細資訊,請參閱 SqlTriggerContext 物件。 |
IsAvailable |
這個屬性可用來判斷內容可用性。 |
WindowsIdentity |
這個屬性是用來擷取呼叫端的 Windows 身分識別。 |
判斷內容可用性
藉由檢查 SqlContext
物件的 IsAvailable
屬性,查詢 SqlContext
類別,以查看目前執行的程式代碼是否正在進程中執行。
IsAvailable
屬性是唯讀的,如果呼叫程式代碼是在 SQL Server 內執行,而且如果可以存取其他 SqlContext
成員,則會傳回 True
。 如果 IsAvailable
屬性傳回 False
,則所有其他 SqlContext
成員都會擲回 InvalidOperationException
,如果使用的話。 如果 IsAvailable
傳回 False
,則任何嘗試開啟連接字串中有 “context connection=true” 的連接物件會失敗。
擷取 Windows 身分識別
在 SQL Server 內執行的 CLR 程式代碼一律會在行程帳戶的內容中叫用。 如果程式代碼應該使用呼叫使用者的身分識別來執行特定動作,而不是 SQL Server 進程識別,則應該透過 SqlContext
物件的 WindowsIdentity
屬性來取得模擬令牌。
WindowsIdentity
屬性會傳回 WindowsIdentity
實例,代表呼叫端的 Windows 身分識別,如果使用 SQL Server 驗證驗證用戶端,則傳回 null。 只有標示 EXTERNAL_ACCESS
或 UNSAFE
許可權的元件才能存取此屬性。
取得 WindowsIdentity
對象之後,呼叫端可以模擬客戶端帳戶,並代表其執行動作。
只有當起始執行預存程式或函式的用戶端使用 Windows 驗證連線到伺服器時,才能透過 SqlContext.WindowsIdentity
來取得呼叫端的身分識別。 如果改用 SQL Server 驗證,則此屬性為 null,而且程式代碼無法模擬呼叫端。
範例
下列範例示範如何取得呼叫用戶端的 Windows 身分識別,並模擬用戶端。
[Microsoft.SqlServer.Server.SqlProcedure]
public static void WindowsIDTestProc()
{
WindowsIdentity clientId = null;
WindowsImpersonationContext impersonatedUser = null;
// Get the client ID.
clientId = SqlContext.WindowsIdentity;
// This outer try block is used to thwart exception filter
// attacks which would prevent the inner finally
// block from executing and resetting the impersonation.
try
{
try
{
impersonatedUser = clientId.Impersonate();
if (impersonatedUser != null)
{
// Perform some action using impersonation.
}
}
finally
{
// Undo impersonation.
if (impersonatedUser != null)
impersonatedUser.Undo();
}
}
catch
{
throw;
}
}