Compartilhar via


SqlContext Object

O código gerenciado é invocado no servidor quando você chama um procedimento ou uma função, quando chama um método em um tipo CLR (Common Language Runtime) definido pelo usuário ou quando sua ação dispara um gatilho definido em qualquer das linguagens do Microsoft .NET Framework. Como a execução desse código é exigida como parte de uma conexão de usuário, o acesso ao contexto do chamador a partir do código em execução no servidor é necessário. Além disso, determinadas operações de acesso a dados podem ser válidas somente se executadas no contexto do chamador. Por exemplo, o acesso a pseudotabelas inseridas e excluídas usadas em operações de gatilho será válido somente no contexto do chamador.

O contexto do chamador é abstraído em um objeto SqlContext. Para obter mais informações sobre os métodos e as propriedades SqlTriggerContext, consulte a documentação de referência da classe Microsoft.SqlServer.Server.SqlTriggerContext no SDK do .NET Framework.

SqlContext fornece acesso aos seguintes componentes:

  • SqlPipe: o objeto SqlPipe representa o "pipe" pelo qual os resultados fluem para o cliente. Para obter mais informações sobre o objeto SqlPipe, consulte Objeto SqlPipe.

  • SqlTriggerContext: o objeto SqlTriggerContext pode ser recuperado somente de dentro um gatilho CLR. Ele fornece informações sobre a operação que fez o gatilho ser acionado e um mapa das colunas que foram atualizadas. Para obter mais informações sobre o objeto SqlTriggerContext, consulte O objeto SqlTriggerContext.

  • IsAvailable: a propriedade IsAvailable é usada para determinar a disponibilidade de contexto.

  • WindowsIdentity: a propriedade WindowsIdentity é usada para recuperar a identidade do Windows do chamador.

Determinando a disponibilidade de contexto

Consulte a classe SqlContext para ver se o código em execução no momento está sendo executado em processo. Para fazer isso, verifique a propriedade IsAvailable do objeto SqlContext. A propriedade IsAvailable é somente leitura e retornará True se o código de chamada estiver em execução no SQL Server e se outros membros de SqlContext puderem ser acessados. Se a propriedade IsAvailable retornar False, todos os outros membros de SqlContext lançarão um InvalidOperationException, se usado. Se IsAvailable retornar False, qualquer tentativa de abrir um objeto de conexão que tem "context connection=true" na cadeia de conexão falhará.

Recuperando a identidade do Windows

O código CLR em execução no SQL Server sempre é invocado no contexto da conta de processo. Se o código deve executar determinadas ações usando a identidade do usuário que fez a chamada em vez da identidade de processo do SQL Server, um token de representação deve ser obtido por meio da propriedade WindowsIdentity do objeto SqlContext. A propriedade WindowsIdentity retorna uma instância WindowsIdentity que representa a identidade do Microsoft do chamador ou que é nula, se o cliente foi autenticado usando a Autenticação do SQL Server. Outros assemblies marcados com EXTERNAL_ACCESS ou permissões UNSAFE podem acessar esta propriedade.

Depois de obter o objeto WindowsIdentity, os chamadores podem representar a conta de cliente e executar ações em seu nome.

A identidade do chamador está disponível por meio de SqlContext.WindowsIdentity somente se o cliente que iniciou a execução do procedimento armazenado ou da função se conectou ao servidor usando a Autenticação do Windows. Se, em vez disso, a Autenticação do SQL Server foi usada, essa propriedade será nula e o código não poderá representar o chamador. O exemplo de representação no CodePlex mostra como usar a representação; consulte Exemplos do Mecanismo de Banco de Dados do SQL Server para obter mais informações.

Exemplo

O exemplo a seguir mostra como obter a identidade do Windows do cliente que fez a chamada e representar o cliente.

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