有时,可能需要获取 Windows 帐户令牌来模拟 Windows 帐户。 例如,基于 ASP.NET 的应用程序可能需要代表多个用户行事。 应用程序可以从 Internet 信息服务 (IIS) 接受一个表示管理员的标记,模拟该用户,执行一项操作,然后还原到以前的身份。 然后,可以从 IIS 接受一个表示拥有较少权限的用户的标记,执行某项操作,并再次还原。
如果应用程序必须模拟尚未由 IIS 附加到当前线程的 Windows 帐户,则必须检索该帐户的令牌并使用它来激活该帐户。 可以通过以下任务来实现这一目标:
通过调用非托管 LogonUser 方法检索特定用户的帐户令牌。 此方法不在 .NET 基类库中,而是位于非托管 advapi32.dll中。 在非托管代码中访问方法是一项高级作,超出了此讨论的范围。 有关详细信息,请参阅与非托管代码交互操作。 有关 LogonUser 方法和 advapi32.dll的详细信息,请参阅平台 SDK 文档。
创建 WindowsIdentity 类的新实例,并传递令牌。 以下代码演示了此调用,其中
hToken
表示 Windows 令牌。WindowsIdentity impersonatedIdentity = new WindowsIdentity(hToken);
Dim impersonatedIdentity As New WindowsIdentity(hToken)
创建 WindowsImpersonationContext 类的新实例,并用已初始化类的 WindowsIdentity.Impersonate 方法对它进行初始化,以开始模拟,如以下代码所示。
WindowsImpersonationContext myImpersonation = impersonatedIdentity.Impersonate();
WindowsImpersonationContext myImpersonation = impersonatedIdentity.Impersonate()
如果不再需要模拟,请调用 WindowsImpersonationContext.Undo 方法来还原模拟,如以下代码所示。
myImpersonation.Undo();
myImpersonation.Undo()
如果受信任的代码已将对象附加到 WindowsPrincipal 线程,则可以调用实例方法 Impersonate,该方法不采用帐户令牌。 请注意,仅当线程上的 WindowsPrincipal 对象表示当前正在执行进程的用户以外的用户时,这才很有用。 例如,使用 ASP.NET 时,可能会遇到这种情况:开启 Windows 身份验证并关闭模拟。 在这种情况下,进程在 Internet Information Services(IIS)中配置的帐户下运行,而当前主体表示正在访问页面的 Windows 用户。
请注意, “模拟 ”和 “撤消 ”都不会更改与当前调用上下文关联的 Principal 对象(IPrincipal)。 相反,模拟和还原会更改与当前操作系统进程关联的标记。