模拟与恢复

注释

本文适用于 Windows。

有关 ASP.NET Core 的信息,请参阅 ASP.NET Core Security

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

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

  1. 通过调用非托管 LogonUser 方法检索特定用户的帐户令牌。 此方法不在 .NET 基类库中,而是位于非托管 advapi32.dll中。 在非托管代码中访问方法是一项高级作,超出了此讨论的范围。 有关详细信息,请参阅与非托管代码交互操作。 有关 LogonUser 方法和 advapi32.dll的详细信息,请参阅平台 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 Information Services(IIS)中配置的帐户下运行,而当前主体表示正在访问页面的 Windows 用户。

请注意, “模拟 ”和 “撤消 ”都不会更改与当前调用上下文关联的 Principal 对象(IPrincipal)。 相反,模拟和还原会更改与当前操作系统进程关联的标记。

另请参阅