保護されたネットワーク共有間で多くのファイルを移動および作成するため、多くの偽装を行う必要があるアプリケーションがあります。メソッドがユーザー、ドメイン、パスワード、および偽装コンテキストで実行する必要があるコードを含むデリゲートを受け取る単純な静的クラスを作成しました。
私が遭遇した問題は、CLR がこのコンテキストで参照されたアセンブリにバインドしようとしたときです。「アクセスが拒否されました」というメッセージとともに FileLoadException がスローされます。
これは、偽装されたユーザーがファイル システムの下の *.DLL ファイルに対して十分な権限を持っていないことが原因であると思われます。たとえば、偽装ブロックの直前に無害なコードを書くことができます。これは、コンテキストが偽装されたユーザーに切り替わる前に、問題のアセンブリから型をロードする以外に何も実行しません。これはうまく機能します。しかし、私はこれがエレガントな解決策であるとは本当に考えていません.偽装で使用できる型について心配し始める必要がありますtypeof()
か?
これをさらにイライラさせるのは、ローカルの開発マシンでこの問題に遭遇しないことです。この問題が発生するのは、アセンブリがベータ環境に出荷されたときです。また、ベータ環境からファイルのアクセス許可を読み取って、ロケーション マシンでそれらを模倣しようとするアクセス権がありません。
いずれにせよ、私はこの解決策を試しました:
// Defined above:
// System.Security.Principal.WindowsIdentity identity;
// System.Security.Principal.WindowsImpersonationContext context;
context = identity.Impersonate();
int tries = 0;
while ( true )
{
try
{
contextAction();
}
catch ( FileLoadException ex )
{
if ( tries > MAX_TRIES )
{
// don't allow an infinite loop
throw;
}
if ( String.IsNullOrEmpty( ex.FileName ) )
{
// if this is null/empty, we can't really recover
throw;
}
context.Undo(); // return to current logon
try
{
var assemblyName = new AssemblyName( ex.FileName );
Assembly.Load( assemblyName );
tries++;
continue;
}
finally
{
context = identity.Impersonate(); // re-impersonate
}
}
finally
{
// return to your current windows logon
context.Undo();
}
}
サイコロはありません。で始まる行を除いて、「アクセスが拒否されました」という例外が引き続き発生しAssembly.Load
ます。
注目すべき興味深い点の 1 つは、ビルド サーバーから同じ例外が発生していたことです。上記のソリューションにより、ビルドサーバーで修正されました。ベータ環境ではありません。
ここで何が欠けていますか?ありがとう。