Compartir a través de


Objeto SqlContext

Se aplica a:SQL Server

Se invoca código administrado en el servidor cuando se llama a un procedimiento o función, cuando se llama a un método en un tipo definido por el usuario de Common Language Runtime (CLR), o cuando la acción desencadena un desencadenador definido en cualquiera de los lenguajes de .NET Framework. Dado que la ejecución de este código se solicita como parte de una conexión de usuario, se requiere el acceso al contexto del autor de la llamada desde el código que se ejecuta en el servidor. Además, ciertas operaciones de acceso a datos solo pueden ser válidas si se ejecutan en el contexto del autor de la llamada. Por ejemplo, el acceso a pseudo tablas insertadas y eliminadas utilizadas en operaciones del desencadenador solo es válido bajo el contexto del autor de la llamada.

El contexto del autor de la llamada se abstrae en un objeto SqlContext. Para obtener más información, vea Microsoft.SqlServer.Server.SqlContext.

SqlContext proporciona acceso a los siguientes componentes.

Componente Descripción
SqlPipe Este objeto representa el de canalización de a través del cual los resultados fluyen al cliente. Para obtener más información, vea objeto SqlPipe.
SqlTriggerContext Este objeto solo se puede recuperar desde un desencadenador CLR. Proporciona información sobre la operación que hizo que se activara el desencadenador y un mapa de las columnas actualizadas. Para obtener más información, vea objeto SqlTriggerContext.
IsAvailable Esta propiedad se usa para determinar la disponibilidad del contexto.
WindowsIdentity Esta propiedad se usa para recuperar la identidad de Windows del autor de la llamada.

Determinación de la disponibilidad del contexto

Consulte la clase SqlContext para ver si el código que se ejecuta actualmente se está ejecutando en proceso comprobando la propiedad IsAvailable del objeto SqlContext. La propiedad IsAvailable es de solo lectura y devuelve True si el código de llamada se ejecuta dentro de SQL Server y si se puede acceder a otros miembros de SqlContext. Si la propiedad IsAvailable devuelve False, todos los demás miembros de SqlContext inician un InvalidOperationException, si se usan. Si IsAvailable devuelve False, se produce un error en cualquier intento de abrir un objeto de conexión que tenga "context connection=true" en la cadena de conexión.

Recuperación de la identidad de Windows

El código CLR que se ejecuta dentro de SQL Server siempre se invoca en el contexto de la cuenta de proceso. Si el código debe realizar determinadas acciones mediante la identidad del usuario que realiza la llamada, en lugar de la identidad del proceso de SQL Server, se debe obtener un token de suplantación a través de la propiedad WindowsIdentity del objeto SqlContext. La propiedad WindowsIdentity devuelve una instancia de WindowsIdentity que representa la identidad de Windows del autor de la llamada o null si el cliente se autenticó mediante la autenticación de SQL Server. Solo los ensamblados marcados con permisos EXTERNAL_ACCESS o UNSAFE pueden acceder a esta propiedad.

Después de obtener el objeto WindowsIdentity, los autores de llamadas pueden suplantar la cuenta de cliente y realizar acciones en su nombre.

La identidad del autor de la llamada solo está disponible a través de SqlContext.WindowsIdentity si el cliente que inició la ejecución del procedimiento almacenado o la función conectada al servidor mediante la autenticación de Windows. Si se usó la autenticación de SQL Server en su lugar, esta propiedad es null y el código no puede suplantar al autor de la llamada.

Ejemplo

En el ejemplo siguiente, se muestra cómo obtener la identidad de Windows del cliente de la llamada y suplantarla.

  • de C#
  • de Visual Basic para .NET
[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;
    }
}