BackgroundWorker
偽装でクラスを使用しようとすると、少し問題があります。Google からの回答に従って、このコードを偽装しました
public class MyImpersonation {
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
public bool impersonateValidUser(String userName, String domain, String password) {
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf()) {
if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0) {
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) {
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null) {
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
}
BackgroundWorker
クラスで使用するまでは、非常にうまく機能していました。この場合、非同期で実行されるコードに偽装を追加しました。エラーはありませんが、非同期メソッドで使用すると偽装が機能しないという問題があります。
コードでは、これは次のようになります。
BGWorker をインスタンス化し、イベント ハンドラーを DoWork イベントに追加します。
_bgWorker = new BackgroundWorker(); _bgWorker.DoWork += new DoWorkEventHandler(_bgWorker_DoWork);
上記のハンドラーでは、何らかのコードを実行する前に偽装が行われます。
private void _bgWorker_DoWork(object sender, DoWorkEventArgs e) { MyImpersonation myImpersonation = new MyImpersonation(); myImpersonation.impersonateValidUser(user, domain, pass) //run some code... myImpersonation.undoImpersonation(); }
コードはで起動されます
BGWorker.RunWorkerAsync();
前に述べたように、エラーはスローされません。コードは、偽装を実行していないかのように動作するだけです。つまり、デフォルトの資格情報が使用されます。
さらに、偽装メソッドは true を返すため、偽装は特定のレベルで発生しましたが、おそらく現在のスレッドでは発生していません。
これは、非同期コードが別のスレッドで実行されるために発生する必要があるため、MyImpersonation
クラスに何かを追加する必要があります。しかし、何?:)