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 ステートメントや分散クエリ、3 部または 4 部構成の識別子を使用する別のデータベースを参照するクエリなどは実行しないでください。コンテキスト スイッチのスコープを、現在のデータベースの外部まで拡張する方法については、「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 値が含まれている場合にのみ、実行コンテキストを以前のコンテキストに戻すことができます。データベース エンジンでは cookie は **@**varbinary_variable に渡されます。

    **@**varbinary_variable のデータ型は varbinary(100) です。

  • CALLER
    モジュール内で使用した場合、モジュールの呼び出し元のコンテキストで、モジュール内のステートメントが実行されます。

    モジュール外で使用した場合、このステートメントでは何も処理されません。

説明

実行コンテキストでの変更は、次のいずれかが行われるまで有効です。

  • 別の 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\SqlUser1SQLUsers のメンバーであり、したがって Sales データベースへのアクセスが暗黙的に許可されている。

この場合、CompanyDomain\SqlUser1SQLUsers グループのメンバーシップを介してデータベースにアクセスできますが、CompanyDomain\SqlUser1 がプリンシパルとしてデータベースに存在しないので、ステートメント EXECUTE AS USER = 'CompanyDomain\SqlUser1' は失敗します。

ユーザーが孤立した (関連付けられたログインが存在しない) 状態になり、かつユーザーが WITHOUT LOGIN で作成されなかった場合、そのユーザーの EXECUTE AS は失敗します。

推奨事項

セッションで操作を実行する場合に必要となる最低限の権限を持つログインまたはユーザーを指定します。たとえば、データベース レベルの権限だけが必要な場合、サーバー レベルの権限が与えられているログイン名は指定しません。また、データベース所有者アカウントは、データベース レベルの権限が必要とされない場合は指定しません。

WITH NO REVERT の使用

EXECUTE AS ステートメントにオプションの WITH NO REVERT 句が含まれている場合、REVERT を使用、または別の EXECUTE AS ステートメントを実行して、セッションの実行コンテキストを元に戻すことはできません。ステートメントで設定されたコンテキストはセッションが削除されるまで有効です。

WITH NO REVERT COOKIE = @varbinary\_variable 句を指定した場合、SQL Server データベース エンジンは cookie 値を @varbinary\_variable に渡します。そのステートメントで設定された実行コンテキストを以前のコンテキストに戻すには、REVERT WITH COOKIE = @varbinary\_variable ステートメントの呼び出し時に、同じ @varbinary\_variable 値が含まれている必要があります。

このオプションは、接続プールが使用されている環境で役立ちます。接続プールには、アプリケーション サーバーのアプリケーションで再利用できるよう、データベース接続のグループが保持されています。@varbinary_variable に渡される値を認識できるのは EXECUTE AS ステートメントの呼び出し元のみであるため、呼び出し元が確立した実行コンテキストは、他のアカウントによって変更されることはありません。

元のログインの特定

SQL Server インスタンスに接続したログインの名前に戻すには、ORIGINAL_LOGIN 関数を使用します。この関数を使用すると、明示的または暗黙的なコンテキスト スイッチが多数行われるセッションで、元のログインの ID を取得できます。

権限

ログインに EXECUTE AS を指定するには、呼び出し元に、指定のログイン名に対する IMPERSONATE 権限が与えられている必要があります。データベース ユーザーに EXECUTE AS を指定するには、呼び出し元に、指定のユーザー名に対する IMPERSONATE 権限が与えられている必要があります。EXECUTE AS CALLER を指定した場合、IMPERSONATE 権限は必要ありません。

A. EXECUTE AS と REVERT を使用してコンテキストを切り替える

次の例では、複数のプリンシパルを使用してコンテキスト実行スタックを作成した後、REVERT ステートメントを使用して実行コンテキストを以前のコンテキストに戻します。REVERT ステートメントは、実行コンテキストが最初の呼び出し元に設定されるまで、スタックの上層に向かって複数回実行されます。

USE AdventureWorks;
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 NO REVERT COOKIE = @varbinary\_variable 句を指定します。コンテキストを正常に呼び出し元に戻すには、REVERT ステートメントで、EXECUTE AS ステートメントの @cookie 変数に渡される値を指定する必要があります。この例を実行するには、例 A で作成したログイン 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