【问题标题】:impersonation and BackgroundWorker模拟和BackgroundWorker
【发布时间】:2009-04-08 16:23:11
【问题描述】:

在尝试将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();
    

正如我之前所说,不会引发错误,只是代码表现得好像我没有运行任何模拟,即使用其默认凭据。

另外,impersonation 方法返回true,所以模拟发生在某个级别,但可能不在当前线程上。

这一定会发生,因为异步代码在另一个线程上运行,所以一定有一些东西需要添加到MyImpersonation 类中。但是什么? :)

【问题讨论】:

  • 如果您提到您在后台工作人员类中遇到的错误类型可能会有所帮助。
  • @Lucian D:我同意 GWLlosa 的观点,如果课程有效,很好,但如果有错误或无效,您需要指定如何操作。
  • 对不起,我已经更正了我的帖子。我希望现在更清楚了:)

标签: c# .net backgroundworker impersonation


【解决方案1】:

我也遇到了同样的问题。我有一个后台工作人员在 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多