プロシージャまたは関数を呼び出すとき、共通言語ランタイム (CLR) ユーザー定義型でメソッドを呼び出すとき、またはアクションが Microsoft .NET Framework 言語で定義されたトリガーを起動するときに、サーバーでマネージド コードを呼び出します。 このコードの実行はユーザー接続の一環として要求されるので、サーバーで実行しているコードから呼び出し元のコンテキストにアクセスできる必要があります。 さらに、特定のデータ アクセス操作は、呼び出し元のコンテキストで実行された場合にのみ有効な場合があります。 たとえば、トリガー操作で使用される inserted 擬似テーブルや deleted 擬似テーブルにアクセスするには、コードが呼び出し元のコンテキストで実行されている必要があります。
呼び出し元のコンテキストは、SqlContext オブジェクトに抽象化されます。
SqlTriggerContextメソッドとプロパティの詳細については、.NET Framework SDK の Microsoft.SqlServer.Server.SqlTriggerContext クラスリファレンス ドキュメントを参照してください。
SqlContext は、次のコンポーネントへのアクセスを提供します。
SqlPipe:SqlPipeオブジェクトは、結果がクライアントに流れる "パイプ" を表します。SqlPipeオブジェクトの詳細については、「SqlPipe オブジェクト」を参照してください。SqlTriggerContext:SqlTriggerContextオブジェクトは、CLR トリガー内からのみ取得できます。 このオブジェクトでは、トリガーを起動した操作や、更新された列のマップについての情報を提供します。SqlTriggerContextオブジェクトの詳細については、「SqlTriggerContext オブジェクト」を参照してください。IsAvailable:IsAvailableプロパティは、コンテキストの可用性を決定するために使用されます。WindowsIdentity:WindowsIdentityプロパティは、呼び出し元の Windows ID を取得するために使用されます。
コンテキストの可用性の決定
SqlContext クラスにクエリを実行して、現在実行中のコードがインプロセスで実行されているかどうかを確認します。 これを行うには、SqlContext オブジェクトのIsAvailable プロパティを確認します。
IsAvailable プロパティは読み取り専用で、呼び出し元のコードが SQL Server 内で実行されていて、他の True メンバーにアクセスできる場合は SqlContext を返します。
IsAvailable プロパティが Falseを返す場合、他のすべての SqlContext メンバーが InvalidOperationExceptionをスローします (使用されている場合)。
IsAvailable が Falseを返した場合、接続文字列で "context connection=true" を持つ接続オブジェクトを開こうとすると失敗します。
Windows ID の取得
SQL Server 内で実行される CLR コードは、常にプロセス アカウントのコンテキストで呼び出されます。 SQL Server プロセス ID ではなく、呼び出し元ユーザーの ID を使用して特定のアクションをコードで実行する必要がある場合は、WindowsIdentity オブジェクトの SqlContext プロパティを使用して偽装トークンを取得する必要があります。
WindowsIdentity プロパティは、呼び出し元の Microsoft Windows ID を表すWindowsIdentity インスタンスを返します。クライアントが SQL Server 認証を使用して認証された場合は null を返します。 このプロパティにアクセスできるのは、EXTERNAL_ACCESS 権限または UNSAFE 権限でマークされたアセンブリだけです。
WindowsIdentity オブジェクトを取得した後、呼び出し元はクライアント アカウントを偽装し、代わりにアクションを実行できます。
呼び出し元の ID は、Windows 認証を使用してサーバーに接続されているストアド プロシージャまたは関数の実行を開始したクライアントの場合にのみ、SqlContext.WindowsIdentity を通じて使用できます。 代わりに SQL Server 認証が使用された場合、このプロパティは null であり、コードは呼び出し元を偽装できません。
例
次の例では、呼び出し元であるクライアントの Windows ID を取得し、クライアントの権限を借用する方法を示します。
C#
[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;
}
}
Visual Basic
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub WindowsIDTestProcVB ()
Dim clientId As WindowsIdentity
Dim impersonatedUser As WindowsImpersonationContext
' 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 IsNot Nothing Then
' Perform some action using impersonation.
End If
Finally
' Undo impersonation.
If impersonatedUser IsNot Nothing Then
impersonatedUser.Undo()
End If
End Try
Catch e As Exception
Throw e
End Try
End Sub
こちらもご覧ください
SqlPipe オブジェクト
SqlTriggerContext オブジェクト
CLR トリガー
SQL Server In-Process ADO.NET に対する特定の拡張機能