Objeto SqlContext
Se invoca el código administrado en el servidor al llamar a un procedimiento o función, al llamar a un método en un tipo definido por el usuario de Common Language Runtime (CLR) o cuando su acción activa un desencadenador definido en cualquiera de los lenguajes de Microsoft .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 bajo 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 resume en un objeto SqlContext. Para obtener más información sobre los métodos y propiedades de SqlTriggerContext, vea la documentación de referencia de clase Microsoft.SqlServer.Server.SqlTriggerContext en .NET Framework SDK.
SqlContext proporciona acceso a los componentes siguientes:
SqlPipe: el objeto SqlPipe representa la "canalización" a través de la que los resultados fluyen al cliente. Para obtener más información acerca del objeto SqlPipe, vea Objeto SqlPipe.
SqlTriggerContext: el objeto SqlTriggerContext 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 acerca del objeto SqlTriggerContext, vea SqlTriggerContext, objeto.
IsAvailable: la propiedad IsAvailable se utiliza para determinar la disponibilidad de contexto.
WindowsIdentity: la propiedad WindowsIdentity se utiliza para recuperar la identidad de Windows del autor de la llamada.
Determinar la disponibilidad del contexto
Consulte la clase SqlContext para ver si el código actualmente en ejecución se ejecuta en proceso. Para ello, compruebe la propiedad IsAvailable del objeto SqlContext. La propiedad IsAvailable es de solo lectura y devuelve True si el código de llamada se está ejecutando dentro de SQL Server y si se puede tener acceso a otros miembros de SqlContext. Si la propiedad IsAvailable devuelve False, todos los demás miembros de SqlContext producen una excepción InvalidOperationException, si se utilizan. Si IsAvailable devuelve False, cualquier intento de abrir un objeto de conexión con "context connection=true" en la cadena de conexión genera un error.
Recuperar 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 utilizando la identidad del usuario que es el autor de 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 en Windows Microsoft del autor de la llamada, o bien, null si el cliente se autenticó utilizando la autenticación de SQL Server. Solo los ensamblados marcados con los permisos EXTERNAL_ACCESS o UNSAFE tienen acceso a esta propiedad.
Después de obtener el objeto WindowsIdentity, los autores de la llamada pueden suplantar la cuenta del 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 función se conectó al servidor utilizando la autenticación de Windows. Si en su lugar se utilizara la autenticación de SQL Server, esta propiedad sería NULL y el código no podría 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.
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