EXECUTE AS 句 (Transact-SQL)
適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance
SQL Server では、関数 (インライン テーブル値関数を除く)、プロシージャ、キュー、トリガーなどのユーザー定義モジュールの実行コンテキストを定義できます。
モジュールが実行されるコンテキストを指定することにより、データベース エンジンがどのユーザー アカウントを使用して、モジュールによって参照されるオブジェクトの権限を検証するかを制御できます。 これにより、ユーザー定義モジュールとそれらのモジュールによって参照されるオブジェクト間に存在する、オブジェクトのチェーン全体に関する権限の管理を、さらに柔軟に制御できます。 ユーザーに付与する必要のある権限は、モジュール自体に対するもののみで、参照されるオブジェクトに対する明示的な権限の許可は必要ありません。 モジュールによってアクセスされるオブジェクトに対する権限が必要なのは、そのモジュールを実行しているユーザーのみです。
構文
このセクションでは、.. の 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 AS
ALTER QUEUE
必要があります。
OWNER
モジュール内のステートメントが、モジュールの現在の所有者のコンテキストで実行されることを指定します。 モジュールに指定された所有者がない場合は、モジュールのスキーマの所有者が使用されます。 OWNER
DDL またはログオン トリガーには指定できません。
重要
OWNER
はシングルトン アカウントにマップする必要があり、ロールまたはグループにすることはできません。
'user_name'
モジュール内のステートメントを、user_name で指定されたユーザーのコンテキスト内で実行します。 モジュール内のすべてのオブジェクトの権限は user_name に対して検証されます。 サーバー スコープまたはログオン トリガーを持つ DDL トリガーには、user_nameを指定できません。 代わりに login_name を使います。
user_name は、現在のデータベース内に存在し、単一アカウントである必要があります。 user_nameは、グループ、ロール、証明書、キー、または組み込みアカウント (例: NT AUTHORITY\LocalService
、NT AUTHORITY\NetworkService
、NT AUTHORITY\LocalSystem
) にすることはできません。
実行コンテキストのユーザー ID はメタデータに格納され、列またはsys.assembly_modules
カタログ ビューでexecute_as_principal_id
sys.sql_modules
表示できます。
'login_name'
モジュール内部のステートメントを、login_name で指定された SQL Server ログインのコンテキストで実行します。 モジュール内のすべてのオブジェクトの権限は login_name に対して検証されます。 login_name は、サーバー スコープの DDL トリガーまたはログオン トリガーのみに指定できます。
login_nameは、グループ、ロール、証明書、キー、または組み込みアカウント (例: NT AUTHORITY\LocalService
、NT AUTHORITY\NetworkService
、NT AUTHORITY\LocalSystem
) にすることはできません。
解説
データベース エンジンによる、モジュール内で参照されるオブジェクトに対する権限の評価方法は、呼び出し元のオブジェクトと参照されるオブジェクト間に存在する所有権の継承によって異なります。 以前のバージョンの SQL Server では、呼び出し元のユーザーに対して、参照されるすべてのオブジェクトへのアクセスを許可するためには、所有権の継承を使用する方法しかありませんでした。
所有権の継承には、次のような制限があります。
- DML ステートメント
SELECT
(、、、INSERT
UPDATE
DELETE
、) にのみ適用されます。 - 呼び出し元のオブジェクトと呼び出されたオブジェクトの所有者は同一である必要があります。
- モジュール内の動的クエリには適用されません。
モジュール内で指定される実行コンテキストに関係なく、次の操作が常に適用されます。
モジュールが実行されると、データベース エンジンは最初に、モジュールを実行しているユーザーがモジュールに対するアクセス許可を持っていることを
EXECUTE
確認します。所有権の継承ルールは、引き続き適用されます。 つまり、呼び出し元のオブジェクトと呼び出されたオブジェクトの所有者が同一の場合、基になるオブジェクトに対する権限は確認されません。
ユーザーが、コンテキスト以外CALLER
のコンテキストで実行するように指定されたモジュールを実行すると、モジュールを実行するためのユーザーのアクセス許可がチェックされますが、モジュールによってアクセスされるオブジェクトに対する追加のアクセス許可チェックは、句で指定されたユーザー アカウントにEXECUTE AS
対して実行されます。 実質的に、モジュールを実行するユーザーは、指定されたユーザーの権限を借用します。
モジュールの句で EXECUTE AS
指定されたコンテキストは、モジュールの実行期間中のみ有効です。 モジュールの実行が完了すると、コンテキストは呼び出し元に戻されます。
ユーザーまたはログイン名を指定する
モジュールの句で EXECUTE AS
指定されたデータベース ユーザーまたはサーバー ログインは、モジュールが別のコンテキストで実行されるように変更されるまで削除できません。
句でEXECUTE AS
指定されたユーザー名またはログイン名は、それぞれプリンシパルsys.database_principals
sys.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
関連するコンテンツ
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示