尝试使用BackgroundWorker
类进行模拟时,我遇到了一些问题。根据谷歌的答案,我得到了这个代码来冒充
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
类。但是什么? :)
答案 0 :(得分:0)
我遇到同样的问题。我有一个后台工作者在DoWork事件中使用静态类进行模拟。我正在尝试模拟另一个Active Domain用户,以便读取主用户无权访问的目录。如果我在IDE中运行应用程序,模拟用户可以毫无问题地读取文件。如果我从文件系统运行应用程序,模拟仍然会发生,但会抛出一个异常,说模拟用户没有访问权限。
从我读过的内容是由于设置了Assembly:SecurityPermissionAttribute和Assembly:PermissionSetAttribute。
在课堂宣言之前我有以下内容:
<Assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True), _
Assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name:="FullTrust")>
在我的StartImpersonating()函数之前,我有:
<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
我正在使用VB.NET而不是C#。
-D