EXECUTE AS 句 (Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

SQL Server では、関数 (インライン テーブル値関数を除く)、プロシージャ、キュー、トリガーなどのユーザー定義モジュールの実行コンテキストを定義できます。

モジュールが実行されるコンテキストを指定することにより、データベース エンジンがどのユーザー アカウントを使用して、モジュールによって参照されるオブジェクトの権限を検証するかを制御できます。 これにより、ユーザー定義モジュールとそれらのモジュールによって参照されるオブジェクト間に存在する、オブジェクトのチェーン全体に関する権限の管理を、さらに柔軟に制御できます。 ユーザーに付与する必要のある権限は、モジュール自体に対するもののみで、参照されるオブジェクトに対する明示的な権限の許可は必要ありません。 モジュールによってアクセスされるオブジェクトに対する権限が必要なのは、そのモジュールを実行しているユーザーのみです。

Transact-SQL 構文表記規則

構文

このセクションでは、.. の SQL Server 構文 EXECUTE ASについて説明します。

関数 (インライン テーブル値関数を除く)、ストアド プロシージャ、および DML トリガー:

{ EXEC | EXECUTE } AS { CALLER | SELF | OWNER | 'user_name' }

データベース スコープを持つ DDL トリガー:

{ EXEC | EXECUTE } AS { CALLER | SELF | 'user_name' }

サーバー スコープとログオン トリガーを含む DDL トリガー:

{ EXEC | EXECUTE } AS { CALLER | SELF | 'login_name' }

キュー:

{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }

Note

SQL Server 2014 (12.x) 以前のバージョンの Transact-SQL 構文を確認するには、以前のバージョンのドキュメントを参照してください。

引数

CALLER

モジュール内のステートメントを、モジュールの呼び出し元のコンテキストで実行します。 モジュールを実行するユーザーは、モジュール自体に対してだけでなく、そのモジュールによって参照されるすべてのデータベース オブジェクトに対する、適切な権限を持っている必要があります。

CALLER は、キューを除くすべてのモジュールの既定値であり、SQL Server 2005 (9.x) の動作と同じです。

CALLERは、or ALTER QUEUE ステートメントでCREATE QUEUE指定できません。

SELF

EXECUTE AS SELF は、指定されたユーザーがモジュールを作成または変更するユーザーである場合と同じです EXECUTE AS <user_name>。 モジュールを作成または変更するユーザーの実際のユーザー ID は、列またはsys.service_queuesカタログ ビューにsys.sql_modules格納されますexecute_as_principal_id

SELF はキューの既定値です。

Note

カタログ ビューのsys.service_queues列のexecute_as_principal_idユーザー ID を変更するには、ステートメントで設定を明示的に指定するEXECUTE ASALTER QUEUE必要があります。

OWNER

モジュール内のステートメントが、モジュールの現在の所有者のコンテキストで実行されることを指定します。 モジュールに指定された所有者がない場合は、モジュールのスキーマの所有者が使用されます。 OWNER DDL またはログオン トリガーには指定できません。

重要

OWNER はシングルトン アカウントにマップする必要があり、ロールまたはグループにすることはできません。

'user_name'

モジュール内のステートメントを、user_name で指定されたユーザーのコンテキスト内で実行します。 モジュール内のすべてのオブジェクトの権限は user_name に対して検証されます。 サーバー スコープまたはログオン トリガーを持つ DDL トリガーには、user_nameを指定できません。 代わりに login_name を使います。

user_name は、現在のデータベース内に存在し、単一アカウントである必要があります。 user_nameは、グループ、ロール、証明書、キー、または組み込みアカウント (例: NT AUTHORITY\LocalServiceNT AUTHORITY\NetworkServiceNT AUTHORITY\LocalSystem) にすることはできません。

実行コンテキストのユーザー ID はメタデータに格納され、列またはsys.assembly_modulesカタログ ビューでexecute_as_principal_idsys.sql_modules表示できます。

'login_name'

モジュール内部のステートメントを、login_name で指定された SQL Server ログインのコンテキストで実行します。 モジュール内のすべてのオブジェクトの権限は login_name に対して検証されます。 login_name は、サーバー スコープの DDL トリガーまたはログオン トリガーのみに指定できます。

login_nameは、グループ、ロール、証明書、キー、または組み込みアカウント (例: NT AUTHORITY\LocalServiceNT AUTHORITY\NetworkServiceNT AUTHORITY\LocalSystem) にすることはできません。

解説

データベース エンジンによる、モジュール内で参照されるオブジェクトに対する権限の評価方法は、呼び出し元のオブジェクトと参照されるオブジェクト間に存在する所有権の継承によって異なります。 以前のバージョンの SQL Server では、呼び出し元のユーザーに対して、参照されるすべてのオブジェクトへのアクセスを許可するためには、所有権の継承を使用する方法しかありませんでした。

所有権の継承には、次のような制限があります。

  • DML ステートメント SELECT(、、、INSERTUPDATEDELETE、) にのみ適用されます。
  • 呼び出し元のオブジェクトと呼び出されたオブジェクトの所有者は同一である必要があります。
  • モジュール内の動的クエリには適用されません。

モジュール内で指定される実行コンテキストに関係なく、次の操作が常に適用されます。

  • モジュールが実行されると、データベース エンジンは最初に、モジュールを実行しているユーザーがモジュールに対するアクセス許可を持っていることをEXECUTE確認します。

  • 所有権の継承ルールは、引き続き適用されます。 つまり、呼び出し元のオブジェクトと呼び出されたオブジェクトの所有者が同一の場合、基になるオブジェクトに対する権限は確認されません。

ユーザーが、コンテキスト以外CALLERのコンテキストで実行するように指定されたモジュールを実行すると、モジュールを実行するためのユーザーのアクセス許可がチェックされますが、モジュールによってアクセスされるオブジェクトに対する追加のアクセス許可チェックは、句で指定されたユーザー アカウントにEXECUTE AS対して実行されます。 実質的に、モジュールを実行するユーザーは、指定されたユーザーの権限を借用します。

モジュールの句で EXECUTE AS 指定されたコンテキストは、モジュールの実行期間中のみ有効です。 モジュールの実行が完了すると、コンテキストは呼び出し元に戻されます。

ユーザーまたはログイン名を指定する

モジュールの句で EXECUTE AS 指定されたデータベース ユーザーまたはサーバー ログインは、モジュールが別のコンテキストで実行されるように変更されるまで削除できません。

句でEXECUTE AS指定されたユーザー名またはログイン名は、それぞれプリンシパルsys.database_principalssys.server_principalsとして存在する必要があります。そうしないと、モジュールの作成または変更操作が失敗します。 また、モジュールを作成または変更するユーザーには、そのプリンシパルに対する IMPERSONATE 権限が必要です。

ユーザーが Windows グループ メンバーシップを介して SQL Server のデータベースまたはインスタンスに暗黙的にアクセスできる場合、次のいずれかの要件が存在する場合、モジュールの作成時に句で EXECUTE AS 指定されたユーザーが暗黙的に作成されます。

  • 指定されたユーザーまたはログインが、固定サーバー ロール sysadmin のメンバーであること。
  • モジュールを作成するユーザーに、プリンシパルを作成する権限が与えられていること。

これらの要件がどちらも満たされない場合、モジュールの作成操作は失敗します。

重要

SQL Server (MSSQL Standard Edition RVER) サービスがローカル アカウント (ローカル サービスまたはローカル ユーザー アカウント) として実行されている場合、この句でEXECUTE AS指定された Windows doメイン アカウントのグループ メンバーシップを取得する権限はありません。 このため、モジュールの実行は失敗します。

たとえば、次のような条件を想定します。

  • CompanyDomain\SQLUsers グループはデータベースにアクセスできます Sales

  • CompanyDomain\SqlUser1 はメンバー SQLUsers であるため、データベースにアクセスできます Sales

  • モジュールを作成または変更するユーザーに、プリンシパルを作成する権限が与えられている。

次の CREATE PROCEDURE ステートメントが実行されると、CompanyDomain\SqlUser1 が、Sales データベースのデータベース プリンシパルとして暗黙的に作成されます。

USE Sales;
GO
CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
AS
SELECT USER_NAME();
GO

EXECUTE AS CALLER スタンドアロン ステートメントを使用する

モジュール内のスタンドアロン ステートメントを EXECUTE AS CALLER 使用して、モジュールの呼び出し元に実行コンテキストを設定します。

次のストアド プロシージャが SqlUser2 によって呼び出されるとします。

CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'SqlUser1'
AS
SELECT USER_NAME(); -- Shows execution context is set to SqlUser1.
EXECUTE AS CALLER;
SELECT USER_NAME(); -- Shows execution context is set to SqlUser2, the caller of the module.
REVERT;
SELECT USER_NAME(); -- Shows execution context is set to SqlUser1.
GO

EXECUTE AS を使用してカスタム アクセス許可セットを定義する

モジュールの実行コンテキストを指定すると、カスタム アクセス許可セットを定義する場合に便利です。 たとえば、許可可能なアクセス許可がないなどの TRUNCATE TABLE 一部のアクションがあります。 モジュール内にステートメントを TRUNCATE TABLE 組み込み、テーブルを変更するアクセス許可を持つユーザーとしてモジュールを実行するように指定することで、モジュールに対するアクセス許可を付与 EXECUTE するユーザーにテーブルを切り捨てる権限を拡張できます。

実行コンテキストを指定したモジュールの定義を表示するには、sys.sql_modules (Transact-SQL) カタログ ビューを使用します。

ベスト プラクティス

モジュール内で定義された操作を実行する場合に必要となる最低限の権限を持つログインまたはユーザーを指定します。 たとえば、これらのアクセス許可が必要な場合を除き、データベース所有者アカウントを指定しないでください。

アクセス許可

指定された EXECUTE ASモジュールを実行するには、呼び出し元にモジュールに対するアクセス許可が EXECUTE 必要です。

別のデータベースまたはサーバー内のリソースにアクセスする AS で EXECUTE 指定された CLR モジュールを実行するには、ターゲット データベースまたはサーバーは、モジュールの送信元データベース (ソース データベース) の認証子を信頼する必要があります。

モジュールを EXECUTE AS 作成または変更するときに句を指定するには、指定したプリンシパルに対するアクセス許可と、モジュールを作成するためのアクセス許可が必要 IMPERSONATE です。 ユーザー自身の権限は、常に借用できます。 実行コンテキストが指定されていない場合、または EXECUTE AS CALLER 指定されている場合、 IMPERSONATE アクセス許可は必要ありません。

Windows グループ メンバーシップを 介してデータベースに暗黙的にアクセスできるlogin_name または user_name を指定するには、データベースに対するアクセス許可が CONTROL 必要です。

次の例では、AdventureWorks2022 データベースでストアド プロシージャを作成して、実行コンテキストを OWNER に割り当てます。

CREATE PROCEDURE HumanResources.uspEmployeesInDepartment @DeptValue INT
    WITH EXECUTE AS OWNER
AS
SET NOCOUNT ON;

SELECT e.BusinessEntityID,
    c.LastName,
    c.FirstName,
    e.JobTitle
FROM Person.Person AS c
INNER JOIN HumanResources.Employee AS e
    ON c.BusinessEntityID = e.BusinessEntityID
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
    ON e.BusinessEntityID = edh.BusinessEntityID
WHERE edh.DepartmentID = @DeptValue
ORDER BY c.LastName,
    c.FirstName;
GO

-- Execute the stored procedure by specifying department 5.
EXECUTE HumanResources.uspEmployeesInDepartment 5;
GO