模拟与恢复

更新:2007 年 11 月

有时可能需要获取 Windows NT 帐户标记以模拟 Windows 帐户。例如,基于 ASP.NET 的应用程序可能必须在不同的时间代表多个用户进行工作。应用程序可以从 Internet 信息服务 (IIS) 接受一个表示管理员的标记,模拟该用户,执行一项操作,然后恢复到以前的身份。然后,可以从 IIS 接受一个表示拥有较少权限的用户的标记,执行某项操作,并再次恢复。

如果应用程序必须模拟一个未通过 IIS 附加到当前线程的 Windows 帐户,则必须检索该帐户的标记并用它来激活该帐户。通过执行下列任务可实现这一目的:

  1. 通过调用非托管的 LogonUser 方法,检索特定用户的帐户标记。此方法不在 .NET Framework 基类库中,而在非托管 advapi32.dll 中。访问非托管代码中的方法是一项高级操作,不在本文的讨论范围之内。有关更多信息,请参见与非托管代码交互操作。有关 LogonUser 方法和 advapi32.dll 的更多信息,请参见 Platform SDK 文档。

  2. 创建 WindowsIdentity 类的一个新实例,并向其传递标记。以下代码说明此调用,其中 hToken 表示一个 Windows 标记。

    WindowsIdentity ImpersonatedIdentity = new WindowsIdentity(hToken);
    
    Dim ImpersonatedIdentity As New WindowsIdentity(hToken)
    
  3. 创建 WindowsImpersonationContext 类的一个新实例,并用已初始化类的 WindowsIdentity.Impersonate 方法对其进行初始化以开始模拟,如以下代码所示。

    WindowsImpersonationContext MyImpersonation = ImpersonatedIdentity.Impersonate();
    
    WindowsImpersonationContext MyImpersonation = ImpersonatedIdentity.Impersonate()
    
  4. 当不再需要模拟时,调用 WindowsImpersonationContext.Undo 方法还原模拟,如以下代码所示。

    MyImpersonation.Undo();
    
    MyImpersonation.Undo()
    

如果受信任代码已将 WindowsPrincipal 对象附加到线程中,则可调用不采用帐户标记的 Impersonate 实例方法。请注意,仅当线程上的 WindowsPrincipal 对象所表示的用户不是当前正在执行进程的用户时,此操作才有用。例如,如果在使用 ASP.NET 时打开 Windows 身份验证并关闭模拟,则可能遇到此情形。这时,进程在一个 Internet 信息服务 (IIS) 中配置的帐户下运行,而当前主体表示正在访问页面的 Windows 用户。

请注意,ImpersonateUndo 均无法更改同当前调用上下文关联的 Principal 对象。相反,模拟和恢复更改同当前操作系统进程关联的标记。

请参见

概念

主体和标识对象

ASP.NET 模拟

将 IIS 身份验证用于 ASP.NET 模拟

参考

WindowsIdentity

WindowsImpersonationContext

其他资源

与非托管代码交互操作