WindowsIdentity.GetCurrent().Impersonate() 做啥

Posted

技术标签:

【中文标题】WindowsIdentity.GetCurrent().Impersonate() 做啥【英文标题】:What does WindowsIdentity.GetCurrent().Impersonate() doWindowsIdentity.GetCurrent().Impersonate() 做什么 【发布时间】:2011-11-09 22:24:33 【问题描述】:

我正在编写一个类来处理在 asp.net、WCF 服务和 WinForms 应用程序中使用的模拟和委托。

根据MSDN,WindowsIdentity.GetCurrent() 返回代表当前 Windows 用户的 WindowsIdentity 对象。

根据MSDN,WindowsIdentity.Impersonate 允许代码模拟不同的 Windows 用户。

那么,模拟当前用户有什么影响,更重要的是,在 Web 应用程序中,WindowsIdentity.GetCurrent() 除了进程启动者身份或已经模拟的最终用户之外,如何返回?

【问题讨论】:

这是一个很长的故事并且有很多限制,但是假设您想代表您的用户(使用他的凭据)在您的网络应用程序中执行操作,例如阅读电子邮件并在页面中显示,这就是模仿的用武之地。 @Russell McClure 我有 web 应用程序和 winforms 应用程序。问题是使用 Kerberos 使用自己的权限将用户传递到 SQL 服务器,但使用进程启动器身份进行日志记录。 Windows 安全性与用户帐户的权限密切相关。尝试为现有帐户分配权限很困难且容易出错。冒充其他用户,获得所需的权限。 【参考方案1】:

如果出现 Win32 错误,Impersonate() 会抛出 SecurityException。因此,很可能是通过 Win32 函数实现的,很可能是ImpersonateLoggedOnUser()。

它的文档说(强调我的):

包括ImpersonateLoggedOnUser 在内的所有模拟函数都允许 如果以下情况之一为真,则请求模拟:

请求的token模拟级别小于SecurityImpersonation,如SecurityIdentificationSecurityAnonymous。 调用者拥有SeImpersonatePrivilege 权限。 一个进程(或调用者登录会话中的另一个进程)使用显式凭据通过LogonUserLsaLogonUser 函数。 认证身份与调用者相同。

因此,我强烈倾向于认为WindowsIdentity.GetCurrent().Impersonate() 将成功地为同一用户建立一个新的模拟层。

关于您问题的第二部分,您似乎将WindowsIdentity.GetCurrent() 与HttpContext.User 混淆了。在 Web 应用程序中,WindowsIdentity.GetCurrent() 始终返回线程所有者(通常为 Network Service),HttpContext.User 返回当前经过身份验证的用户(如果有)。

【讨论】:

所以,听起来它什么都不做。 不,远非如此。它实际上创建新的模拟层。 Impersonate() 返回一个WindowsImpersonationContext,之后您必须将其发送到Undo(),以便将该层从堆栈中弹出并避免泄漏模拟上下文。 我的问题源于我在谷歌搜索的几个页面中看到 WindowsIdentity.GetCurrent().Impersonate()。我得到了线程所有者和 HttpContext 用户之间的区别。我担心在某些情况下 WindowsIdentity.GetCurrent() 会返回当前线程所有者身份以外的内容。如果总是一样,听起来 Impersonate() 确实模拟了,但是对当前的 WindowsIdentity 这样做有什么影响或理由吗? 效果是让处理网络请求的线程冒充其他用户,所以它确实很有用,但我很困惑:你是说你在某处找到了类似WindowsIdentity.GetCurrent().Impersonate() 的代码网络?如果是这样,您能否使用该代码的相关部分更新您的问题? 仍然没有人回答再次冒充当前用户有什么好处,这是最初的问题。是的,它为同一用户创建了一个新的模拟上下文。但是为什么要这样做呢?【参考方案2】:

如果您必须通过多个应用程序(包括通常允许匿名访问的一些应用程序)运行用户,则当前用户很重要。此外,它还允许您显式执行某些类型的应用程序中隐式执行的操作。

从您的角度来看,更重要的事情可能是了解并非所有应用程序类型都会以您希望的方式自动获取启动用户类型。在这些情况下,在某些情况下,您可以通过编程方式完成获取身份,然后将其用于您自己的方式(恶意或其他方式?)。

至于模拟另一个用户,当您脱离某些声明性情况(如 ASP.NET 模拟)时,这会变得很有趣。这是有充分理由的,例如,黑客不会创建具有上帝般权利的应用程序。

【讨论】:

以上是关于WindowsIdentity.GetCurrent().Impersonate() 做啥的主要内容,如果未能解决你的问题,请参考以下文章