Partilhar via


EXECUTE AS (Transact-SQL)

Define o contexto de execução de uma sessão.

Por padrão, uma sessão é iniciada quando um usuário faz logon e é encerrada quando ele faz logoff. Todas as operações durante uma sessão estão sujeitas a verificações de permissão para aquele usuário. Quando uma instrução EXECUTE AS é executada, o contexto de execução da sessão é alternado para o logon ou nome de usuário específico. Depois da alternância de contexto, as permissões são verificadas no logon e nos tokens de segurança do usuário para a conta, em vez da pessoa que chama a instrução EXECUTE AS. Em essência, o usuário ou a conta de logon são representados durante a execução da sessão ou do módulo, ou a alternância de contexto é explicitamente revertida. Para obter mais informações sobre contexto de execução, consulte Compreendendo o contexto de execução. Para obter mais informações sobre alternância de contexto, consulte Compreendendo alternância de contexto.

Ícone de vínculo de tópicoConvenções de sintaxe Transact-SQL

Sintaxe

{ EXEC | EXECUTE } AS <context_specification>
[;]

<context_specification>::=
{ LOGIN | USER } ='name'
    [ WITH { NO REVERT | COOKIE INTO @varbinary_variable } ] 
| CALLER

Argumentos

  • LOGIN
    Especifica que o contexto de execução a ser representado é um logon. O escopo de representação é em nível de servidor.

  • USER
    Especifica que o contexto a ser representado é um usuário no banco de dados atual. O escopo de personificação é restringido ao banco de dados atual. Uma opção de contexto para um usuário de banco de dados não herda as permissões em nível de servidor desse usuário.

    Observação importanteImportante

    Enquanto a opção de contexto para o usuário do banco de dados estiver ativa, qualquer tentativa de acessar os recursos fora do banco de dados provocará falha na instrução. Isso inclui instruções USE database, consultas distribuídas e consultas que fazem menção a outro banco de dados que usa identificadores em três ou quatro partes. Para estender o escopo da alternância de contexto fora do banco de dados atual, consulte Estendendo representação de banco de dados com EXECUTE AS.

  • 'name'
    É um nome de logon ou usuário válido. name deve ser um membro da função de servidor fixa sysadmin ou existir como uma entidade em sys.database_principals ou sys.server_principals, respectivamente.

    name pode ser especificado como uma variável local.

    name deve ser uma conta singleton e não pode ser um grupo, função, certificado, chave ou conta interna, como NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService ou NT AUTHORITY\LocalSystem.

    Para obter mais informações, consulte Especificando um nome de logon ou usuário mais adiante neste tópico.

  • NO REVERT
    Especifica que a alternância de contexto não pode ser revertida para o contexto anterior.

    Para obter mais informações sobre como reverter para o contexto anterior, consulte REVERT (Transact-SQL).

  • COOKIE INTO @varbinary_variable
    Especifica que o contexto de execução só poderá ser revertido para o contexto anterior se a instrução de chamada REVERT WITH COOKIE contiver o valor correto @varbinary_variable . O Mecanismo de Banco de Dados passa o cookie para @varbinary_variable.

    @ varbinary_variable é varbinary(100).

  • CALLER
    Quando usado em um módulo, especifica que as instruções dentro dele são executadas no contexto do chamador do módulo.

    Quando usado fora de um módulo, a instrução não tem nenhuma ação.

Comentários

A alteração no contexto de execução permanece em vigor até que uma das seguintes situações ocorra:

  • Outra instrução EXECUTE AS é executada.

  • Uma instrução REVERT é executada.

  • A sessão é descartada.

Você pode criar uma pilha de contexto de execução chamando a instrução EXECUTE AS várias vezes em várias entidades. Quando chamada, a instrução REVERT alterna o contexto para o logon ou usuário no próximo nível acima da pilha de contexto. Para obter uma demonstração desse comportamento, consulte o Exemplo A.

Especificando um nome de logon ou usuário

O nome de usuário ou de logon especificado em EXECUTE AS <context_specification> deve existir como uma entidade em sys.database_principals ou sys.server_principals, respectivamente; caso contrário, a instrução EXECUTE AS falhará. Além disso, as permissões IMPERSONATE devem ser concedidas na entidade. A menos que o chamador seja o proprietário do banco de dados ou membro da função de servidor fixa sysadmin, a entidade deverá existir quando o usuário estiver acessando o banco de dados ou a instância do SQL Server por meio de uma associação de grupo do Windows. Por exemplo, considere as seguintes condições:

  • O grupo CompanyDomain\SQLUsers tem acesso ao banco de dados Sales.

  • O CompanyDomain\SqlUser1 é um membro de SQLUsers e, por isso, tem acesso implícito ao banco de dados Sales.

Embora CompanyDomain\SqlUser1 tenha acesso ao banco de dados por meio de associação no grupo SQLUsers, a instrução EXECUTE AS USER = 'CompanyDomain\SqlUser1' falhará porque CompanyDomain\SqlUser1 não existe como uma entidade no banco de dados.

Se o usuário ficou órfão (o logon associado não existe mais) e ele não foi criado com WITHOUT LOGIN, EXECUTE AS falhará para o usuário.

Prática recomendada

Especifique um logon ou usuário que tenha pelo menos os privilégios necessários para executar as operações da sessão. Por exemplo, não especifique um nome de logon com permissões em nível de servidor se apenas as permissões em nível de banco de dados forem necessárias; ou não especifique uma conta de proprietário de banco de dados, a menos que essas permissões sejam necessárias.

Observação sobre cuidadosCuidado

A instrução EXECUTE AS pode ser bem-sucedida, desde que o Mecanismo de Banco de Dados possa resolver o nome. Se existir um usuário de domínio, o Windows poderá resolver o usuário para o Mecanismo de Banco de Dados, embora o usuário Windows não tenha acesso ao SQL Server. Isso pode levar a uma condição em que um logon sem acesso ao SQL Server pareça estar conectado, embora o logon representado só tenha as permissões concedidas a público ou convidado.

Usando WITH NO REVERT

Quando a instrução EXECUTE AS inclui a cláusula opcional WITH NO REVERT, o contexto de execução de uma sessão não pode ser redefinido usando REVERT ou executando outra instrução EXECUTE AS. O contexto definido pela instrução permanece até que a sessão seja descartada.

Quando a cláusula WITH NO REVERT COOKIE = @varbinary_variable é especificada, o Mecanismo de banco de dados do SQL Server passa o valor do cookie para @varbinary_variable. O contexto de execução definido pela instrução só poderá ser revertido para o contexto anterior se a instrução de chamada REVERT WITH COOKIE = @varbinary_variable contiver o mesmo valor @varbinary_variable .

Esta opção é útil em um ambiente no qual um pool de conexão é usado. O pool de conexão é a manutenção de um grupo de conexões de banco de dados para reutilização por aplicativos em um servidor de aplicativos. Como o valor passado para @varbinary_variable é conhecido apenas pelo chamador da instrução EXECUTE AS (no caso, o aplicativo), o chamador pode garantir que o contexto de execução estabelecido não possa ser alterado por mais ninguém.

Determinando o logon original

Use a função ORIGINAL_LOGIN para retornar o nome do logon que conectou à instância do SQL Server. Você pode usar essa função para retornar a identidade do logon original em sessões nas quais há muitas alternâncias de contexto explícitas ou implícitas.

Permissões

Para especificar EXECUTE AS em um logon, o chamador precisa ter permissões IMPERSONATE no nome de logon especificado. Para especificar EXECUTE AS em um usuário de banco de dados, o chamador precisa ter permissões IMPERSONATE no nome de usuário especificado. Quando EXECUTE AS CALLER é especificado, as permissões IMPERSONATE não são necessárias.

Exemplos

A. Usando EXECUTE AS e REVERT para alternar o contexto

O exemplo a seguir cria uma pilha de execução de contexto usando várias entidades. A instrução REVERT é usada para redefinir o contexto de execução para o chamador anterior. A instrução REVERT é executada várias vezes movendo a pilha para cima até o contexto de execução ser definido como o chamador original.

USE AdventureWorks2008R2;
GO
--Create two temporary principals
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
GO
CREATE USER user1 FOR LOGIN login1;
CREATE USER user2 FOR LOGIN login2;
GO
--Give IMPERSONATE permissions on user2 to user1
--so that user1 can successfully set the execution context to user2.
GRANT IMPERSONATE ON USER:: user2 TO user1;
GO
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
-- Set the execution context to login1. 
EXECUTE AS LOGIN = 'login1';
--Verify the execution context is now login1.
SELECT SUSER_NAME(), USER_NAME();
--Login1 sets the execution context to login2.
EXECUTE AS USER = 'user2';
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
-- The execution context stack now has three principals: the originating caller, login1 and login2.
--The following REVERT statements will reset the execution context to the previous context.
REVERT;
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();
REVERT;
--Display current execution context.
SELECT SUSER_NAME(), USER_NAME();

--Remove temporary principals.
DROP LOGIN login1;
DROP LOGIN login2;
DROP USER user1;
DROP USER user2;
GO

O exemplo a seguir define o contexto de execução de uma sessão para um usuário determinado e especifica a cláusula REVERT WITH COOKIE = @varbinary_variable. A instrução REVERT deve especificar o valor passado para a variável @cookie na instrução EXECUTE AS para reverter com êxito o contexto de volta para o chamador. Para executar este exemplo, o logon login1 e o usuário user1 criados no exemplo A devem existir.

DECLARE @cookie varbinary(100);
EXECUTE AS USER = 'user1' WITH COOKIE INTO @cookie;
-- Store the cookie in a safe location in your application.
-- Verify the context switch.
SELECT SUSER_NAME(), USER_NAME();
--Display the cookie value.
SELECT @cookie;
GO
-- Use the cookie in the REVERT statement.
DECLARE @cookie varbinary(100);
-- Set the cookie value to the one from the SELECT @cookie statement.
SET @cookie = <value from the SELECT @cookie statement>;
REVERT WITH COOKIE = @cookie;
-- Verify the context switch reverted.
SELECT SUSER_NAME(), USER_NAME();
GO