EXECUTE AS (Transact-SQL)

Задает контекст выполнения для сеанса.

По умолчанию сеанс запускается при входе пользователя в систему и завершается при выходе пользователя из системы. Все операции во время сеанса подлежат проверке на наличие у пользователя соответствующих разрешений. При запуске инструкции EXECUTE AS контекст выполнения сеанса переключается на заданное имя входа и имя пользователя. После переключений контекста имя входа и пользовательские токены безопасности для этой учетной записи проходят проверку на соответствие разрешениям (а не пользователь, вызвавший инструкцию EXECUTE AS). В сущности, либо входная или пользовательская учетная запись олицетворяется на время сеанса или на время выполнения модуля, либо явно обращается переключение контекста. Дополнительные сведения о контексте выполнения см. в разделе Основные сведения о контексте выполнения. Дополнительные сведения о переключении контекста см. в разделе Основные сведения о переключении контекста.

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

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

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

Аргументы

  • LOGIN
    Указывает, что контекст выполнения олицетворения — это имя входа. Область олицетворения — это уровень сервера.

  • USER
    Определяет контекст для олицетворения пользователя в текущей базе данных. Область олицетворения ограничена текущей базой данных. При переключении контекста на пользователя базы данных разрешения уровня сервера этого пользователя не наследуются.

    Важное примечаниеВажно!

    Пока переключение контекста на пользователя базы данных активно, любая попытка подключиться к ресурсам вне базы данных будет приводить к завершению инструкции с ошибками. Это касается инструкций USE database, распределенных запросов, а также запросов, которые ссылаются на другую базу данных, использующую трех- и четырехчастные идентификаторы. Сведения о расширении области переключения контекста за пределы текущей базы данных см. в разделе Расширение олицетворения базы данных с помощью инструкции EXECUTE AS.

  • 'name'
    Допустимое имя пользователя или имя входа. Пользователь name должен быть членом предопределенной роли сервера sysadmin или быть зарегистрирован в качестве участника в представлении sys.database_principals или sys.server_principals соответственно.

    name можно задавать как локальную переменную.

    Учетная запись name должна быть одноэлементной и не может быть группой, ролью, сертификатом, ключом или встроенной учетной записью, например NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService или NT AUTHORITY\LocalSystem.

    Дополнительные сведения см. в разделе Указание имени пользователя или имени входа далее.

  • NO REVERT
    Указывает, что переключение контекста нельзя вернуть к предыдущему контексту.

    Дополнительные сведения о переключении к предыдущему контексту см. в разделе REVERT (Transact-SQL).

  • COOKIE INTO @varbinary_variable
    Указывает, что контекст выполнения можно переключить к предыдущему контексту, если при вызове инструкция REVERT WITH COOKIE содержит правильное значение @varbinary_variable . Компонент Database Engine передает куки-файл в @varbinary_variable.

    Аргумент @varbinary_variable имеет тип varbinary(100).

  • CALLER
    При использовании внутри модуля указывает, что инструкции модуля выполняются в контексте вызывающей стороны.

    При использовании вне модуля инструкция не действует.

Замечания

Изменение в контексте выполнения продолжает действовать до тех пор, пока не произойдет одно из следующих событий.

  • Будет запущена еще одна инструкция EXECUTE AS.

  • Будет запущена инструкция REVERT.

  • Сеанс удаляется.

Набор контекстов выполнения может быть создан при помощи нескольких вызовов инструкции EXECUTE AS на нескольких участниках. При вызове инструкция REVERT производит переключение контекста на имя входа или на пользователя на более высоком уровне стека контекстов. Это показано в разделе Пример А.

Указание пользователя или имени входа

Указанный в предложении EXECUTE AS <указание_контекста> пользователь (или имя входа) должен существовать в качестве участника в sys.database_principals или sys.server_principals соответственно, в противном случае инструкция завершится ошибкой. Кроме того, этому участнику должны быть предоставлены разрешения IMPERSONATE. Если процедура вызывается не владельцем базы данных и не членом предопределенной роли сервера sysadmin, указанный участник должен существовать даже в том случае, если пользователь производит доступ к базе данных или экземпляру SQL Server в качестве члена группы Windows. Для примера рассмотрим следующие условия.

  • Группа CompanyDomain\SQLUsers имеет доступ к базе данных Sales.

  • Пользователь CompanyDomain\SqlUser1 является членом группы SQLUsers и поэтому неявно имеет доступ к базе данных Sales.

Хотя пользователь CompanyDomain\SqlUser1 имеет доступ к базе данных в силу членства в группе SQLUsers, инструкция EXECUTE AS USER = 'CompanyDomain\SqlUser1' завершится ошибкой, так как CompanyDomain\SqlUser1 не существует в качестве участника в базе данных.

Если пользователь утратил связь с учетной записью (соответствующее имя входа больше не существует), а пользователь не был создан с параметром WITHOUT LOGIN, попытка этого пользователя выполнить команду EXECUTE AS завершится неудачно.

Рекомендации

Указывайте имя входа или пользователя, который имеет наименьшие права доступа, необходимые для выполнения операций в сеансе. Например, не указывайте имя входа с разрешениями уровня сервера, если требуются разрешения только уровня базы данных, а также не указывайте учетную запись владельца базы данных, если только эти разрешения не являются обязательными.

ПредупреждениеВнимание!

Инструкция EXECUTE AS может быть выполнена успешно, так как компонент Database Engine может разрешить это имя. Если пользователь домена существует, то Windows сможет разрешить пользователя для компонента Database Engine, хотя пользователь Windows не имеет доступа к SQL Server. Это может привести к ситуации, когда пользователь, не имеющий доступа к SQL Server, сможет войти в систему, хотя олицетворенное имя входа будет иметь только те разрешения, которые были предоставлены пользователю public или guest.

Применение WITH NO REVERT

Если инструкция EXECUTE AS содержит необязательное предложение WITH NO REVERT, то контекст выполнения для сеанса нельзя сбросить с помощью инструкции REVERT или путем выполнения другой инструкции EXECUTE AS. Контекст, заданный инструкцией, остается до удаления сеанса.

Если указано предложение WITH NO REVERT COOKIE = @varbinary_variable, то компонент SQL Server Database Engine передает значение куки-файла в @varbinary_variable. Контекст выполнения, задаваемый этой инструкцией, может вернуться к предыдущему контексту только в том случае, если вызывающая инструкция REVERT WITH COOKIE = @varbinary_variable содержит то же значение @varbinary_variable .

Этот параметр может пригодиться в среде с организацией пула соединений. Организация пула соединений — это поддержка группы соединений базы данных для повторного использования приложениями или сервером приложений. Поскольку значение, передаваемое в @varbinary_variable, известно только инициатору инструкции EXECUTE AS, то инициатор может гарантировать, что установленный им контекст выполнения больше никто не сможет изменить.

Определение первоначального имени входа

Функция ORIGINAL_LOGIN возвращает имя входа, которое подключилось к экземпляру SQL Server. Эту функцию можно использовать для получения учетных данных первоначального входного имени в сеансах, в которых происходит много явных и неявных переключений контекста.

Разрешения

Чтобы указать в предложении EXECUTE AS имя входа, вызывающая сторона должна иметь разрешения IMPERSONATE на указанное имя входа. Чтобы указать в предложении EXECUTE AS пользователя базы данных, вызывающая сторона должна иметь разрешения IMPERSONATE на указанное имя входа. Если указан параметр EXECUTE AS CALLER, то разрешения IMPERSONATE не являются обязательными.

Примеры

A. Использование предложений EXECUTE AS и REVERT для переключения контекста

В приведенном примере создается стек контекстов выполнения с использованием нескольких участников. Затем инструкция REVERT используется для сброса контекста выполнения к предыдущему участнику. Инструкция REVERT выполняется множество раз, передвигаясь вверх по стеку до тех пор, пока контекст выполнения не будет установлен на первоначального участника.

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

Следующий образец устанавливает контекст выполнения сеанса для определенного пользователя и указывает предложение REVERT WITH COOKIE = @varbinary_variable. Инструкция REVERT обязана указать значение, передаваемое переменной @cookie в инструкции EXECUTE AS, чтобы успешно вернуть контекст вызывающему коду. Чтобы запустить этот образец, должно существовать имя входа login1 и пользователь user1, созданные в примере А.

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