调用过程或函数时、在公共语言运行时(CLR)用户定义类型上调用方法或作触发任何 Microsoft .NET Framework 语言中定义的触发器时,会在服务器中调用托管代码。 由于在用户连接过程中需要执行此代码,因此需要从服务器上运行的代码访问调用方的上下文。 此外,只有在调用方上下文下运行时,某些数据访问作才有效。 例如,访问触发器操作中使用的插入和删除的伪表只在调用方的上下文中有效。
调用方上下文在 SqlContext 对象中抽象化。 有关方法和属性的详细信息 SqlTriggerContext ,请参阅 Microsoft.SqlServer.Server.SqlTriggerContext .NET Framework SDK 中的类参考文档。
SqlContext 提供对以下组件的访问:
SqlPipe:对象SqlPipe表示结果流向客户端的“管道”。 有关对象SqlPipe的详细信息,请参阅 SqlPipe 对象。SqlTriggerContextSqlTriggerContext:只能在 CLR 触发器中检索对象。 它提供有关导致触发器被激发的操作的信息,以及所更新的列的映射。 有关对象SqlTriggerContext的详细信息,请参阅 SqlTriggerContext 对象。IsAvailable:该IsAvailable属性用于确定上下文可用性。WindowsIdentity:该WindowsIdentity属性用于检索调用者的 Windows 标识。
确定上下文可用性
SqlContext查询类以查看当前正在执行的代码是否正在进程内运行。 为此,请检查 IsAvailable 对象的属性 SqlContext 。
IsAvailable 属性是只读的,如果调用代码在 SQL Server 中运行,并且可以访问其他 True 成员,则返回 SqlContext。 如果 IsAvailable 属性返回 False,则所有其他 SqlContext 成员将引发 InvalidOperationException(如果使用)。 如果 IsAvailable 返回 False,则尝试打开连接字符串中具有“context connection=true”的连接对象将失败。
检索 Windows 标识
在 SQL Server 内执行的 CLR 代码始终在进程帐户的上下文中调用。 如果代码应使用调用用户的标识执行某些操作,而不是 SQL Server 进程标识,则应通过 WindowsIdentity 对象的 SqlContext 属性获取模拟令牌。 该 WindowsIdentity 属性返回一个 WindowsIdentity 实例,该实例表示调用方Microsoft Windows 标识;如果使用 SQL Server 身份验证对客户端进行身份验证,则返回 null。 只有标记为 EXTERNAL_ACCESS 或 UNSAFE 权限的程序集才能访问此属性。
获取 WindowsIdentity 对象后,调用方可以模拟客户端帐户并代表其执行作。
仅当启动执行存储过程或函数的客户端使用 Windows 身份验证连接到服务器的存储过程或函数时,才能通过 SqlContext.WindowsIdentity 调用方的身份。 如果改用了 SQL Server 身份验证,则此属性为 null,并且代码无法模拟调用方。
示例:
下面的示例说明如何获取调用客户端的 Windows 标识并模拟该客户端。
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 的特定扩展