SqlContext 对象

适用于:SQL Server

调用过程或函数时,在公共语言运行时 (CLR) 用户定义的类型调用方法,或者当操作触发以任何 Microsoft .NET Framework 语言定义的触发器时,可以在服务器中调用托管代码。 由于在用户连接过程中需要执行此代码,因此需要从服务器上运行的代码访问调用方的上下文。 此外,某些数据访问操作只有在调用方的上下文中运行时才有效。 例如,访问触发器操作中使用的插入和删除的伪表只在调用方的上下文中有效。

调用方上下文在 SqlContext 对象中抽象化。 有关 SqlTriggerContext 方法和属性的详细信息,请参阅 .NET Framework SDK 中的 Microsoft.SqlServer.Server.SqlTriggerContext 类参考文档。

SqlContext 提供对以下组件的访问:

  • SqlPipeSqlPipe 对象表示结果流经到客户端的“管道”。 有关 SqlPipe 对象的详细信息,请参阅 SqlPipe 对象

  • SqlTriggerContext:只能从 CLR 触发器中检索 SqlTriggerContext 对象。 它提供有关导致触发器被激发的操作的信息,以及所更新的列的映射。 有关 SqlTriggerContext 对象的详细信息,请参阅 SqlTriggerContext 对象

  • IsAvailableIsAvailable 属性用于确定上下文可用性。

  • WindowsIdentityWindowsIdentity 属性用于检索调用方 Windows 标识。

确定上下文可用性

查询 SqlContext 类,查看当前正在执行的代码是否在进程中运行。 为此,检查 SqlContext 对象的 IsAvailable 属性。 IsAvailable 属性是只读的,如果调用代码在 SQL Server 中运行,并且可以访问其他 SqlContext 成员,则返回 True。 如果 IsAvailable 属性返回 False,则所有其他 SqlContext 成员将引发 InvalidOperationException(如果使用)。 如果 IsAvailable 返回 False,则任何尝试打开连接字符串中具有“context connection=true”的连接对象都失败。

检索 Windows 标识

在 SQL Server 内部执行的 CLR 代码始终在进程帐户的上下文中调用。 如果代码应使用调用用户的标识(而不是SQL Server进程标识)执行某些操作,则应通过 SqlContext 对象的 WindowsIdentity 属性获取模拟令牌。 WindowsIdentity 属性返回表示调用方 Microsoft Windows 标识的 WindowsIdentity 实例;如果客户端使用SQL Server身份验证进行身份验证,则返回 null。 只有标记为 EXTERNAL_ACCESSUNSAFE 权限的程序集才能访问此属性。

获取 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 进程内专用的 ADO.NET 扩展