EXECUTE AS (Transact-SQL)

Применимо к:SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure Azure Synapse Analytics

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

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

Соглашения о синтаксисе Transact-SQL

Синтаксис

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

Примечание.

Сведения о синтаксисе Transact-SQL для SQL Server 2014 (12.x) и более ранних версиях см . в документации по предыдущим версиям.

Аргументы

ВХОД
Применимо: SQL Server 2008 (10.0.x) и более поздних версий.

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

Примечание.

Этот параметр недоступен в автономной базе данных, База данных SQL Azure или Azure Synapse Analytics.

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

Важно!

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

name — допустимое имя пользователя или имя входа. Аргумент name должен принадлежать предопределенной роли сервера sysadmin либо быть субъектом в базе данных sys.database_principals или sys.server_principals соответственно.

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

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

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

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

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

COOKIE INTO @varbinary_variable
Указывает, что контекст выполнения можно вернуть к предыдущему контексту, если при вызове инструкция REVERT WITH COOKIE содержит правильное значение @varbinary_variable. Ядро СУБД передает файл cookie в @varbinary_variable. Параметр COOKIE INTO можно использовать только на нерегламентированном уровне.

@varbinary_variable — это varbinary(8000).

Примечание.

Параметр OUTPUT файла cookie в настоящее время описан в документации как varbinary(8000), что верно определяет его максимальную длину. Однако текущая реализация возвращает параметр varbinary(100). Для продолжения правильной работы в случае увеличения размера файлов cookie в последующих версиях в приложении должен быть зарезервирован тип varbinary(8000).

ВЫЗЫВАЮЩИЙ
При использовании внутри модуля указывает, что инструкции модуля выполняются в контексте вызывающей стороны. При использовании вне модуля инструкция не действует.

Примечание.

Этот параметр недоступен в Azure Synapse Analytics.

Замечания

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

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

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

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

  • Работа хранимой процедуры или триггера, где выполнялась команда, завершается.

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

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

Имя пользователя или имя входа, указанное в инструкции EXECUTE AS <context_specification>, должно быть субъектом в базе данных sys.database_principals или sys.server_principals соответственно, в противном случае инструкция EXECUTE AS будет завершена с ошибками. Кроме того, этому участнику должны быть предоставлены разрешения 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 может завершиться успешно, пока ядро СУБД может разрешить имя. Если пользователь домена существует, Windows может разрешить пользователя для ядро СУБД, даже если у пользователя Windows нет доступа к SQL Server. Это может привести к условию, когда имя входа без доступа к SQL Server, как представляется, вошедшего в систему, хотя олицетворенный вход будет иметь только разрешения, предоставленные общедоступным или гостевым пользователям.

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

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

Если указано предложение WITH NO REVERT COOKIE = @varbinary_variabl e, sql Server ядро СУБДпередает значение файла cookie в @varbinary_variable. Контекст выполнения, устанавливаемый данной инструкцией, можно возвратить только к предыдущему контексту, если вызов инструкции REVERT WITH COOKIE = @varbinary_variable содержит то же значение @varbinary_variable.

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

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

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

Разрешения

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

Примеры

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

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

USE AdventureWorks2022;  
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  

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

DECLARE @cookie VARBINARY(8000);  
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(8000);  
-- 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  

См. также

REVERT (Transact-SQL)
Предложение EXECUTE AS (Transact-SQL)