EXECUTE AS (Transact-SQL)
適用対象: SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
セッションの実行コンテキストを設定します。
既定では、セッションはユーザーがログインしたときに開始し、ユーザーがログオフしたときに終了します。 セッション中のすべての操作で、ユーザーに対する権限の確認が行われます。 EXECUTE AS ステートメントを実行するとき、セッションの実行コンテキストは指定したログインまたはユーザー名に切り替えられます。 コンテキスト切り替えの後は、EXECUTE AS ステートメントを呼び出したログインまたはユーザーではなく、コンテキスト スイッチのアカウントに関連するログインとユーザーのセキュリティ トークンに対して権限の確認が行われます。 実質的に、ユーザーまたはログイン アカウントは、セッションまたはモジュールの実行中、あるいはコンテキスト スイッチが明示的に戻されるまで続けて借用されます。
構文
{ EXEC | EXECUTE } AS <context_specification>
[;]
<context_specification>::=
{ LOGIN | USER } = 'name'
[ WITH { NO REVERT | COOKIE INTO @varbinary_variable } ]
| CALLER
Note
SQL Server 2014 (12.x) 以前のバージョンの Transact-SQL 構文を確認するには、以前のバージョンのドキュメントを参照してください。
引数
Login
適用対象: SQL Server 2008 (10.0.x) 以降。
権限を借用する実行コンテキストがログインであることを指定します。 権限借用のスコープはサーバー レベルです。
Note
このオプションは、包含データベースまたは Azure SQL データベース または Azure Synapse Analytics では使用できません。
User
権限を借用するコンテキストが、現在のデータベース内のユーザーであることを指定します。 権限借用のスコープは、現在のデータベースに限定されます。 コンテキスト スイッチの対象がデータベース ユーザーであっても、そのユーザーのサーバー レベルの権限は継承されません。
重要
データベース ユーザーに対するコンテキスト スイッチがアクティブであるときに、データベース外部のリソースへアクセスを試みると、ステートメントが失敗する原因となります。 たとえば、USE database ステートメントや分散クエリ、3 部または 4 部構成の識別子を使用する別のデータベースを参照するクエリなどは実行しないでください。
'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) です。
Note
Cookie の OUTPUT パラメーターは現在、適切な最大長である varbinary(8000) としてドキュメントに記載されています。 ただし、現在の実装では varbinary(100) を返します。 将来のリリースでクッキーの戻り値のサイズが増えた場合にアプリケーションが引き続き正常に動作するように、アプリケーションでは varbinary(8000) を予約しておく必要があります。
CALLER
モジュール内で使用した場合、モジュールの呼び出し元のコンテキストで、モジュール内のステートメントが実行されます。
モジュール外で使用した場合、このステートメントでは何も処理されません。
Note
Azure Synapse Analyticsでは、このオプションは使用できません。
解説
実行コンテキストでの変更は、次のいずれかが行われるまで有効です。
別の EXECUTE AS ステートメントの実行
REVERT ステートメントの実行。
セッションの停止
コマンドが実行されたストアド プロシージャまたはトリガーの終了
複数のプリンシパルで複数回、EXECUTE AS ステートメントを呼び出すと、実行コンテキストのスタックを作成できます。 これを実行すると、REVERT ステートメントにより、コンテキスト スタックの次の上位レベルのログインまたはユーザーにコンテキストが切り替えられます。 この動作のデモについては、「例 A」をご覧ください。
ユーザーまたはログイン名の指定
EXECUTE AS <context_specification> で指定されているユーザーまたはログイン名は、sys.database_principals または sys.server_principals のそれぞれに、プリンシパルとして存在する必要があります。存在しない場合、EXECUTE AS ステートメントは失敗します。 さらに、プリンシパルで IMPERSONATE 権限が許可されている必要があります。 呼び出し元がデータベース所有者または固定サーバー ロール sysadmin のメンバーでない場合は、ユーザーが Windows グループ メンバーシップによって SQL Server のデータベースやインスタンスにアクセスしているときでも、プリンシパルは存在する必要があります。 たとえば、次のような条件を想定します。
CompanyDomain\SQLUsers グループに Sales データベースへのアクセス権がある。
CompanyDomain\SqlUser1 は SQLUsers のメンバーであり、したがって Sales データベースへのアクセスが暗黙的に許可されている。
この場合、CompanyDomain\SqlUser1 は SQLUsers グループのメンバーシップを介してデータベースにアクセスできますが、CompanyDomain\SqlUser1
がプリンシパルとしてデータベースに存在しないので、ステートメント EXECUTE AS USER = 'CompanyDomain\SqlUser1'
は失敗します。
ユーザーが孤立した (関連付けられたログインが存在しない) 状態になり、かつユーザーが WITHOUT LOGIN で作成されなかった場合、そのユーザーに対する EXECUTE AS は失敗します。
推奨事項
セッションで操作を実行する場合に必要となる最低限の権限を持つログインまたはユーザーを指定します。 たとえば、データベース レベルの権限だけが必要な場合、サーバー レベルの権限が与えられているログイン名は指定しません。また、データベース所有者アカウントは、データベース レベルの権限が必要とされない場合は指定しません。
注意事項
EXECUTE AS ステートメントは、データベース エンジンが名前を解決できる限り、正常に実行できます。 ドメイン ユーザーが存在する場合、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 データベース エンジンはクッキー値を @varbinary_variable に渡します。 そのステートメントによって設定された実行コンテキストを以前のコンテキストに戻すことができるのは、REVERT WITH COOKIE = @varbinary_variable ステートメントの呼び出し時に、同じ @varbinary_variable 値が含まれている場合のみです。
このオプションは、接続プールが使用されている環境で役立ちます。 接続プールには、アプリケーション サーバーのアプリケーションで再利用できるよう、データベース接続のグループが保持されています。 @varbinary_variable に渡される値を認識できるのは EXECUTE AS ステートメントの呼び出し元のみであるため、呼び出し元が確立した実行コンテキストは、他のアカウントによって変更されることはありません。
元のログインの特定
SQL Server のインスタンスに接続したログインの名前に戻すには、ORIGINAL_LOGIN 関数を使用します。 この関数を使用すると、明示的または暗黙的にコンテキストが何度も切り替えられるセッションにおける、元のログインの ID を取得できます。
アクセス許可
ログインで EXECUTE AS を指定するには、呼び出し元に、指定のログイン名に対する IMPERSONATE 権限が与えられている必要があり、また IMPERSONATE ANY LOGIN 権限が拒否されていないことも条件となります。 データベース ユーザーに EXECUTE AS を指定するには、呼び出し元に、指定のユーザー名に対する IMPERSONATE 権限が与えられている必要があります。 EXECUTE AS CALLER を指定した場合、IMPERSONATE 権限は必要ありません。
例
A. 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
B. WITH COOKIE 句を使用する
次の例では、セッションの実行コンテキストを、指定したユーザーに設定し、WITH COOKIE INTO @varbinary_variable 句を指定します。 コンテキストを正常に呼び出し元に戻すには、REVERT
ステートメントで、EXECUTE AS
ステートメントの @cookie
変数に渡される値を指定する必要があります。 この例を実行するには、例 A で作成したログイン 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