これを解決してよかったですが、所有権の継承は推奨されるソリューションではありません。関係する権利のセキュリティと適切な細分性について正当に懸念しているように思われるので、この返信を追加します。何が起こっているのか、およびこの問題を解決する方法への参照として遅くなりました。
EXECUTE AS偽装スコープ
EXECUTE AS句には、EXECUTE AS LOGINとEXECUTE AS USERの2種類があります。EXECUTE AS LOGINはサーバーによって認証され、SQLインスタンス全体(サーバースコープ)によって信頼される偽装コンテキストです。
EXECUTE AS LOGINステートメントを使用してプリンシパルを偽装する場合、またはEXECUTE AS句を使用してサーバースコープのモジュール内で偽装する場合、偽装のスコープはサーバー全体です。つまり、コンテキストの切り替え後、偽装ログインが権限を持つサーバー内のすべてのリソースにアクセスできます。
EXECUTE AS USERはデータベースによって認証され、そのデータベースのみが信頼する偽装コンテキストです(データベーススコープ)。
ただし、EXECUTE AS USERステートメントを使用してプリンシパルを偽装する場合、またはEXECUTE AS句を使用してデータベーススコープのモジュール内で使用する場合、偽装のスコープはデフォルトでデータベースに制限されます。つまり、データベースのスコープ外のオブジェクトを参照すると、エラーが返されます。
EXECUTE AS句を含むストアドプロシージャは、データベーススコープの偽装コンテキストを作成するため、データベース内のオブジェクトを参照するmsdb.dbo.sp_start_job
ことはできませんmsdb
。サーバースコープDMVへのアクセスの試行、リンクサーバーの使用の試行、Service Brokerメッセージの別のデータベースへの配信の試行など、利用可能な他の多くの例があります。
データベーススコープの偽装が、通常は偽装コンテキストの認証者に許可されないリソースにアクセスできるようにするには、信頼する必要があります。データベーススコープの偽装の場合、オーセンティケーターはデータベースdboです。これは、次の2つの方法で実現できます。
- 偽装コンテキストを認証したデータベース(つまり、EXECUTE AS句が発行されたデータベース)でTRUSTWORTHYプロパティをオンにする。
- コード署名を使用する。
これらの詳細は、MSDN:EXECUTE ASを使用したデータベース偽装の拡張で説明されています。
データベース間の所有権の連鎖を介して問題を解決すると、サーバーレベル全体でクロスDBの連鎖が有効になり、セキュリティリスクと見なされます。目的の結果を達成するための最も制御された細かい方法は、コード署名を使用することです。
- アプリケーションデータベースで自己署名証明書を作成します
dbo.StartAgentJob
この証明書で署名する
- 証明書の秘密鍵を削除する
- 証明書をディスクにエクスポートする
- に証明書をインポートする
msdb
- インポートされた証明書から派生ユーザーを作成する
msdb
- の派生ユーザーにAUTHENTICATE権限を付与します
msdb
これらの手順により、プロシージャのEXECUTE ASコンテキストがでdbo.StartAgentJob
信頼されるようmsdb
になります。これは、コンテキストがでAUTHENTICATE権限を持つプリンシパルによって署名されているためmsdb
です。これでパズルの半分が解けます。残りの半分はmsdb.dbo.sp_start_job
、現在信頼されている偽装コンテキストにEXECUTEパーミッションを実際に付与することです。これを行う方法はいくつかあります。
- 偽装したユーザー
agentProxy
userをマッピングし、msdb
実行権限を付与しますmsdb.dbo.sp_start_job
msdb
オーセンティケーター証明書から派生したユーザーに実行権限を付与する
- プロシージャに新しいシグネチャを追加し、そのためのユーザーを派生させ、
msdb
この派生ユーザーに実行権限を付与します
オプション1.は単純ですが、大きな欠点があります。agentProxy
ユーザーはmsdb.dbo.sp_start_job
自分の意志で実行できるようになり、本当にアクセス権が付与されmsdb
、実行権限が与えられます。
オプション3は正解ですが、私は不必要にやりすぎだと思います。
したがって、私が優先するのはオプション2:でmsdb.dbo.sp_start_job
作成された証明書から派生したユーザーにEXECUTEパーミッションを付与することですmsdb
。
対応するSQLは次のとおりです。
use [<appdb>];
go
create certificate agentProxy
ENCRYPTION BY PASSWORD = 'pGFD4bb925DGvbd2439587y'
with subject = 'agentProxy'
, start_date='01/01/2009';
go
ADD SIGNATURE TO OBJECT::[StartAgentJob]
BY CERTIFICATE [agentProxy]
WITH PASSWORD = 'pGFD4bb925DGvbd2439587y';
go
alter certificate [agentProxy]
remove private key;
go
backup certificate [agentProxy]
to file='c:\temp\agentProxy.cer';
go
use msdb
go
create certificate [agentProxy]
from file='c:\temp\agentProxy.cer';
go
create user [agentProxyAuthenticator]
from certificate [agentProxy];
go
grant authenticate to [agentProxyAuthenticator];
grant execute on msdb.dbo.sp_start_job to [agentProxyAuthenticator];
go
use [<appdb>];
go
exec dbo.StartAgentJob;
go
私のブログには、Service Brokerでアクティブ化されたプロシージャ(EXECUTE AS句が必要なため)のコンテキストで記述された、このトピックに関する記事がいくつかあります。
ところで、私のスクリプトをテストしようとしていて、東半球または英国の夏に住んでいる場合は、テストする前にリンクした最後の記事を必ず読んでください。