EXECUTE AS (Transact-SQL)

適用対象:SQL ServerAzure SQL データベースAzure SQL Managed InstanceAzure 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  

引数

LOGIN
Applies to: SQL Server 2008 (10.0.x) 以降。

権限を借用する実行コンテキストがログインであることを指定します。 権限借用のスコープはサーバー レベルです。

Note

このオプションは、包含データベース、Azure SQL Database、または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 などのビルトイン アカウントにすることはできません。

詳しくは、後の「ユーザーまたはログイン名の指定」をご覧ください。

いや REVERT
コンテキスト スイッチを以前のコンテキストに戻せないことを示します。 NO REVERTオプションはアドホックレベルでのみ使用可能です。

前の文脈に戻す方法の詳細については、 REVERT (Transact-SQL)を参照してください。

cookie into @varbinary_variable
実行コンテキストは、呼び出し REVERT WITH COOKIE文が正しい @varbinary_variable 値を含む場合にのみ、前のコンテキストに戻せることを指定します。 データベース エンジンはクッキーを@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\SqlUser1SQLUsers のメンバーであり、したがって Sales データベースへのアクセスが暗黙的に許可されている。

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

ユーザーが孤児(関連するログインが存在しない場合)で、かつLOGINなしで作成されていない場合、EXECUTE ASは失敗します。

推奨事項

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

注意事項

EXECUTE AS文は、データベース エンジンが名前を解決できる限り成功します。 ドメイン ユーザーが存在する場合、Windows ユーザーがSQL Serverにアクセスできない場合でも、Windowsはデータベース エンジンのユーザーを解決できる可能性があります。 これにより、SQL Serverへのアクセス権を持たないログインがログインしているように見えますが、偽装されたログインにはパブリックまたはゲストにのみアクセス許可が付与されます。

セキュリティの考慮事項

例えば、文 EXECUTE AS USER = 'dbo'を使ってdbo所有権コンテキストで実行すると、明示的な DENY 権限の評価方法が変わります。 実行コンテキストをDBO所有コンテキストに切り替えると、元の呼び出し主体に適用される権限ベースの DENY 制限は、模倣期間中は適用されません。 その結果、db_owner固定データベースロールのメンバーシップを通じて実行コンテキストをdboに切り替えられるプリンシパルは、そのプリンシパルに明示的な DENY 権限が適用されなければブロックされるようなアクションを実行できるようになります。

この動作は設計によるものです。 所有権の偽装を許可するアクセス許可を付与するときに考慮してください。 DENY 権限は、DBOとして実行可能なプリンシパルの有効権限を制限する補償的なコントロールとして機能しません。

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文の呼び出し側のみが知っているため、呼び出し側は確立した実行コンテキストが他の誰にも変更されないことを保証できます。

元のログインの特定

ORIGINAL_LOGIN 関数を使用して、SQL Serverのインスタンスに接続されているログインの名前を返します。 この関数を使用すると、明示的または暗黙的にコンテキストが何度も切り替えられるセッションにおける、元のログインの ID を取得できます。

アクセス許可

ログイン時に EXECUTE AS を指定するには、発信者が指定されたログイン名に対して IMPOSATE 権限を持ち、い かなる LOGIN 権限も拒否されてはなりません。 データベースユーザーに EXECUTE AS を指定するには、呼び出し者が指定されたユーザー名に対して IMPERSONATE 権限を持つ必要があります。 EXECUTE ASCALLERが指定されている場合、なりすまし権限は不要です。

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  

次の例では、セッションの実行コンテキストを指定したユーザーに設定し、WITH COOKIE INTO @varbinary_variable 句を指定します。 コンテキストを正常に呼び出し元に戻すには、REVERT ステートメントで、@cookie ステートメントの EXECUTE AS 変数に渡される値を指定する必要があります。 この例を実行するには、例 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  

参照

REVERT (Transact-SQL)
EXECUTE AS 条項(Transact-SQL)