実行コンテキストについて

実行コンテキストは、セッションに接続するかモジュールを実行し (呼び出し) たユーザーまたはログインによって決まります。実行コンテキストにより、ステートメントまたはアクションを実行する権限と照合する ID が作成されます。実行コンテキストは、ログイン トークンとユーザー トークンというセキュリティ トークンの組で表現します。セキュリティ トークンによって、権限を照合するプライマリ プリンシパルおよびセカンダリ プリンシパルと、トークンの認証元が特定されます。SQL Server インスタンスに接続するログインは、1 つのログイン トークン、およびそのアカウントでアクセスできるデータベースの数に応じた 1 つ以上のユーザー トークンを所有します。

ユーザー セキュリティ トークンとログイン セキュリティ トークン

ユーザー セキュリティ トークンおよびログイン セキュリティ トークンに含まれる内容は次のとおりです。

  • プライマリ ID としてのサーバーまたはデータベースのプリンシパル 1 つ

  • セカンダリ ID としてのプリンシパル 1 つ以上

  • 認証子 0 個以上

  • プライマリ ID およびセカンダリ ID の特権および権限

プリンシパルは、SQL Server リソースを要求できる個人、グループ、およびプロセスです。プリンシパルは効力のスコープによって、Windows レベル、SQL Server レベル、データベース レベルに分類されます。詳細については、「プリンシパル (データベース エンジン)」を参照してください。

認証子はトークンの正当性を保証するプリンシパル、証明書、または非対称キーです。多くの場合、トークンの認証子には SQL Server インスタンスが使用されます。認証子の詳細については、「EXECUTE AS の使用によるデータベースの権限借用の拡張」を参照してください。証明書および非対称キーの詳細については、「暗号化階層」を参照してください。

ログイン トークンは SQL Server インスタンス全体で使用できます。このトークンに含まれるプライマリ ID およびセカンダリ ID は、サーバーレベルの権限および ID に関連するデータベースレベルの権限と照合されます。プライマリ ID はログイン自体を示します。セカンダリ ID には、ロールとグループから継承された権限が含まれます。

ユーザー トークンは特定のデータベースに対してのみ有効です。このトークンに含まれるプライマリ ID およびセカンダリ ID は、データベースレベルの権限と照合されます。プライマリ ID はデータベース ユーザー自体を示します。セカンダリ ID には、データベース ロールから継承された権限が含まれます。ユーザー トークンはサーバーロールのメンバーシップを含んでいないので、サーバーレベルの public ロールに与えた権限を含め、トークン内の ID に与えたサーバーレベルの権限が無視されます。

SQL Server ログイン アカウントを明示的に作成した場合、そのアカウントについて作成されたログイン ID はログイン トークンのプライマリ ID として使用されます。ユーザー アカウントについてもこれと同様です。プリンシパルが SQL Server インスタンスへの暗黙のアクセス許可を所有している (つまり、CONTROL SERVER 権限によってデータベースへのアクセス許可を所有している) 場合、ログイン トークンのプライマリ ID は既定の public ロールです。ユーザー トークンのプライマリ ID は public です。

重要な注意事項重要

sysadmin 固定サーバー ロールのメンバーは、ユーザー トークンのプライマリ ID として常に dbo を所有します。

ログイン トークンの例

Mary は自分の Windows アカウント MyDomain\Mary にマップされた SQL Server ログインを持っています。Mary が自分用に作成されたログイン トークンについての情報を参照するには、次のステートメントを実行します。

SELECT principal_id, sid, name, type, usage FROM sys.login_token;
GO

SELECT principal_id, sid, name, type, usage FROM sys.login_token;
GO

結果セットは次のようになります。

principal_id sid name type usage

------------ ----------- ------------- -------------- -------------

261 0x583EA MyDomain\Mary WINDOWS LOGIN GRANT OR DENY

2 0x02 public SERVER ROLE GRANT OR DENY

(2 row(s) affected)

この結果セットから、Mary の Windows アカウントがログイン トークンのプライマリ ID であることがわかります。Mary のログイン アカウントを作成するときに作成された principal_id が、ログイン トークンではプライマリの principal_id として使用されています。Mary は既定の public ロールのメンバーであるので、セカンダリ ID としてこのロールが表示されます。Mary が他のサーバーベースのロールのメンバーである場合、そのロールもセカンダリ ID として表示されます。ログインを作成したときに、SQL Server インスタンスによって Mary の Windows アカウントは検証されています。そのため、Mary が SQL Server インスタンスにログインすると、そのインスタンスは Mary のログイン トークンの認証子になります。SQL Server インスタンスが Mary のログイン トークンの認証子なので、プリンシパル、証明書、非対称キーなどの認証子はクエリで返ってきません。

ユーザー トークンの例

Mary は、自分がアクセス許可を持っているデータベースごとにユーザー トークンを 1 つずつ持っています。最初の例では、Mary が master データベースに接続します。Mary 用に作成された master データベースのユーザー トークンについての情報を参照するには、次のステートメントを実行します。

SELECT principal_id, sid, name, type, usage FROM sys.user_token;
GO

SELECT principal_id, sid, name, type, usage FROM sys.user_token;
GO

結果セットは次のようになります。

principal_id sid name type usage

------------ ----------- ------------- -------------- -------------

2 NULL guest SQL USER GRANT OR DENY

0 NULL public ROLE GRANT OR DENY

(2 row(s) affected)

この結果セットから、Mary が master データベースの明示的なユーザーではなく、guest アカウントを使用してアクセスしていることがわかります。Mary のユーザー トークンのプライマリ ID は guest ユーザーです。guest は既定の public ロールのメンバーであるので、セカンダリ ID としてこのロールが表示されます。Mary の master データベースのユーザー トークンには、guest ユーザーおよび public ロールが行使できるデータベースレベルのすべての特権および権限が含まれています。

次の例では、Sales データベースに Mary の明示的なユーザー アカウントを作成してあります。さらに、このデータベースの db_ddladmin 固定データベース ロールに Mary を追加しました。Sales を現在のデータベースにして、Mary が再度 SELECT * FROM sys.user_token を実行します。

結果セットは次のようになります。

principal_id sid name type usage

------------ ----------- ------------- -------------- -------------

5 0x36CC4BBD1 Mary SQL USER GRANT OR DENY

0 NULL public ROLE GRANT OR DENY

16387 NULL db_ddladmin ROLE GRANT OR DENY

結果セットには、Sales データベースに作成した Mary のユーザー トークンが反映されています。Mary は Sales データベースにユーザーとして明示的に追加されているので、プライマリ ID として表示されます。Mary が属している 2 つのロールがセカンダリ ID として表示されます。Mary のユーザー トークンの認証子は SQL Server インスタンスです。

実行コンテキストの切り替え

SQL Server では、EXECUTE AS ステートメントにユーザー名またはログイン名を指定することで、セッションの実行コンテキストを明示的に変更できます。ストアド プロシージャ、トリガー、ユーザー定義関数などのモジュールの場合、モジュールの定義の EXECUTE AS 句にユーザー名またはログイン名を指定することで、実行コンテキストを暗黙的に変更できます。他のユーザーまたはログインに実行コンテキストを切り替えると、そのアカウントのログイン トークンおよびユーザー トークンと権限が照合されます。実は、セッションまたはモジュール実行の間、そのアカウントの権限が借用されます。詳細については、「コンテキストの切り替えについて」を参照してください。