8

プラグインを個別の子アプリ ドメインにロードする必要があるアプリケーションを開発しています。1 つの子アプリ ドメインに読み込まれるプラグインは 1 つだけです。各プラグインには異なる Windows ID が必要であり、それらの ID は既定 (親) アプリ ドメインで使用される Windows ID とは異なります。各プラグインは、1 つ以上の子プラグインをロードします。

たとえば、既定のアプリ ドメインの ID はAuthority\Limitedです(権限はドメイン名またはマシン名のいずれかです)。2 つのプラグインが 2 つの子アプリ ドメインに読み込まれます。読み込まれたプラグインの ID は、Authority\Privileged1およびAuthority\Privileged2です。Authority\Privileged1Authority\Privileged2には、それぞれデータベースDatabase1Database2へのすべての必要なアクセス権がありますが、 Authority\Limitedには前述のデータベースへのアクセス権はありません。

子アプリ ドメインを作成するときに、System.Security.Principal.WindowsPrincipalインスタンスを渡してSystem.AppDomain.SetThreadPrincipalメソッドを呼び出します。インスタンスは、複製されたユーザー トークンから作成されたSystem.Security.Principal.WindowsIdentityインスタンスから作成されました ( http://support.microsoft.com/kb/306158を参照)。WindowsIdentity.Impersonateメソッドの呼び出しを省略しました。これは、 WIndowsPrincipalインスタンスの作成中に既定のアプリ ドメインにいるためです。

アプリ ドメインのスレッド プリンシパルを設定するだけで、読み込まれたプラグインがそれぞれのデータベースに正常にログインし、いくつかの T-SQL ステートメントを実行できると予想していました。驚いたことに、WindowsIdentity.GetCurrent()メソッドによって返された値は、データベースへの接続を開くときに使用されます。メソッドによって返される値は、プロセス ID または偽装 ID のいずれかです。

プロセス ID には、データベースを操作するために必要なアクセス許可がないため、受け入れられません。したがって、なりすましが機能するようになる必要があります。ただし、偽装は子アプリ ドメインでのみ行う必要があります。各プラグインは、プラグインのロードとアンロードを実行するために使用されるメソッドを公開します。これらのメソッドの最初に偽装を実行し、最後に偽装を元に戻す必要があることを理解しています。ただし、子アプリ ドメインで生成されたすべてのスレッドに対しても偽装を行う必要があります。各プラグインは 1 つ以上の子プラグインをロードし、各プラグインは 1 つ以上のスレッドを生成する可能性があるため、多くの場所で偽装を実行する必要があり、非常に面倒です。

偽装を1 回だけ実行して、子アプリ ドメインで生成されたすべてのスレッドに影響を与えることはできますか?

4

1 に答える 1

4

いいえ、それはできません。偽装はスレッドごとであり、同じスレッドがコール スタック上の複数の AppDomain からのコードを持つことができます。これは、(一部のメイン AppDomain からの) メイン コードが別の AppDomain でプラグインのロジックを呼び出すプラグイン システムに特に当てはまります。

基本的に、プラグインを呼び出す前に偽装し、完了したら元に戻す必要があります。プラグインが独自の操作にスレッドプールを使用する場合は、適切に偽装する必要があることに注意してください。

于 2011-01-29T20:19:14.820 に答える