C# .NET 3.5 を使用するように書き換えている古い Win32 C++ DCOM サーバーがあります。クライアント アプリケーションは、リモートの Windows XP マシン上にあり、C++ で記述されています。これらのクライアントは変更しないでおく必要があるため、新しい .NET オブジェクトにインターフェイスを実装する必要があります。
これは完了しており、インターフェイスの実装に関しては正常に機能しており、古いクライアントから新しい .NET オブジェクトへのすべての呼び出しが正しく行われています。
しかし、DCOM クライアントから呼び出し元のユーザーの ID を取得するのに問題があります。DCOM 呼び出しを扇動したユーザーを特定するために、サーバー上に次のコードがあります...
[DllImport("ole32.dll")]
static extern int CoImpersonateClient();
[DllImport("ole32.dll")]
static extern int CoRevertToSelf();
private string CallingUser
{
get
{
string sCallingUser = null;
if (CoImpersonateClient() == 0)
{
WindowsPrincipal wp = System.Threading.Thread.CurrentPrincipal as WindowsPrincipal;
if (wp != null)
{
WindowsIdentity wi = wp.Identity as WindowsIdentity;
if (wi != null && !string.IsNullOrEmpty(wi.Name))
sCallingUser = wi.Name;
}
if (CoRevertToSelf() != 0)
ReportWin32Error("CoRevertToSelf");
}
else
ReportWin32Error("CoImpersonateClient");
return sCallingUser;
}
}
private static void ReportWin32Error(string sFailingCall)
{
Win32Exception ex = new Win32Exception();
Logger.Write("Call to " + sFailingCall + " FAILED: " + ex.Message);
}
プロパティを取得するとCallingUser
、最初の数回は正しい値が返され、正しいユーザー名が識別されますが、3 人または 4 人の異なるユーザーが正常に呼び出しを行うと (状況はさまざまであるため、より具体的には言えません)、他のユーザーは、以前に電話をかけたユーザーとして識別されているようです。
私が気付いたのは、最初の数人のユーザーが独自のスレッドで処理される DCOM 呼び出し (つまり、特定のクライアントからのすべての呼び出しが単一の一意のスレッドによって処理される) であり、その後、後続のユーザーが同じスレッドによって処理されることです。の呼び出し後、CoImpersonateClient()
そのCurrentPrincipal
スレッドの最初のユーザーと一致します。
説明する:
ユーザー Tom は、スレッド 1 によって処理される DCOM 呼び出しを行います ( CurrentPrincipal
Tom を正しく識別します) 。
ユーザー Dick は、スレッド 2 によって処理される DCOM 呼び出しを行います ( CurrentPrincipal
Dick を正しく識別します) 。
ユーザー Harry は、スレッド 3 によって処理される DCOM 呼び出しを行います ( CurrentPrincipal
Harry を正しく識別します) 。
ユーザー Bob は、スレッド 3 によって処理される DCOM 呼び出しを行います (CurrentPrincipal
誤って彼を Harry と識別します)。
この図でわかるように、クライアント Harry と Bob からの呼び出しはスレッド 3 で処理され、サーバーは呼び出し元のクライアントを Harry として識別しています。
私が間違っていることはありますか?このように偽装を使用する際の注意事項や制限はありますか? 私がやろうとしていることを確実に達成できる、より良い方法または別の方法はありますか?
すべての助けをいただければ幸いです。