【问题标题】:asp.net impersonation identity: Where does it come from?asp.net 冒充身份:从何而来?
【发布时间】:2011-03-01 08:23:50
【问题描述】:

这是一个我已经坚持了一段时间的简单问题。

当我在 web.config 中设置 < identity impersonate=true > 以便 asp.net 自动模拟登录用户(或匿名帐户,如果不使用 Windows 身份验证)时,asp.net 模拟的身份来自哪里?

本文档:http://msdn.microsoft.com/en-us/library/ff649264.aspx 显示了您可以检索登录用户信息的三个位置:

  • Httpcontext.Current.user
  • System.Threading.Thread.Current
  • System.Security.Principal.WindowsIdentity.GetCurrent
  • 当我在 web.config 中设置 < identity impersonate=true > 时,这些位置似乎都没有与被模拟的身份一致。

    我想知道假冒身份的来源。

    具体来说,我的意思是在低级别询问,在运行时究竟从哪里检索身份。我熟悉 IIS 的配置,但我想知道在运行时如何检索身份以及它来自哪里。为了便于讨论,我们假设身份是在 IIS 中设置的,而不是在 web.config 文件中。

    【问题讨论】:

      标签: asp.net security authentication impersonation


      【解决方案1】:

      如果我没记错的话,这是在 IIS 中设置的身份。目录安全。

      【讨论】:

      • 不是我要找的答案 - 这个答案设置了如何在配置中设置身份。我想知道它是在运行时从哪里检索到的。
      【解决方案2】:

      过去,我将身份设置为在 web.config 文件中模拟。 在这种情况下,我创建了一个用户,将应用程序池设置为该用户下,并使用该用户名进行模拟。

      【讨论】:

      • 仍然不是我正在寻找的答案。我询问如何配置模拟。我知道该怎么做。我在问运行时模拟身份从何而来?
      【解决方案3】:

      启用模拟后,身份来自 IIS。发生的情况是 ASP.NET 模拟 IIS 提供的访问令牌。

      用于运行进程的原始访问令牌仍然可用。这可能是问题中提到的三个 API 使用混淆的根源。

      Thread.CurrentPrincipal & HttpContext.Current.User:线路另一端用户的身份。

      • 这是通过模拟令牌传递给 ASP.NET 的信息
      • 此令牌成为基于以下内容动态创建的身份:
      • 任一:a) 用户如何登录(表单与 Windows 身份验证),
      • 或:b) web.config 中的模拟用户名设置是什么。

      WindowsIdentity.GetCurrent:正在执行的实际底层 Windows 帐户。

      • 这是在 ASP.NET 开始模拟之前启动进程的方式。
      • 这将只是一个 WindowsIdentity。

      HttpContext.Current.User 中重复的原因是为了方便 ASP.NET 开发人员。

      编辑:

      当 IIS 配置为在集成 Windows 身份验证下运行时,并且 ASP.NET 启用了模拟,以下代码将使我们能够以底层帐户运行代码。

      [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern bool RevertToSelf();
      
      protected void Page_Load(object sender, EventArgs e)
      {
          var me = WindowsIdentity.GetCurrent();
      
          // At this point:
          // me.Name = Domain\UserName
          // me.AuthenticationType = Kerberos
      
          if (RevertToSelf())
          {
              var underMe = WindowsIdentity.GetCurrent();
              // At this point:
              // underMe.Name = IIS APPPOOL\DefaultAppPool
              // underMe.AuthenticationType = Negotiate
          }
      }
      

      根据您要执行的操作,此页面有更多解决问题的方法:http://support.microsoft.com/kb/306158

      【讨论】:

      • 您说用于运行进程的原始访问令牌用于模拟...我假设您的意思是 IIS 进程。但是,我不确定如果您将 IIS 配置为使用 Windows Authentication,那么 IIS 将模拟登录用户的令牌。
      • 如果您查看此文档:msdn.microsoft.com/en-us/library/ff649264.aspx,您会发现根据 MS 的说法,WindowsIdentity.GetCurrent 是我们使用模拟时三个 API 用户名中唯一发生变化的一个。
      • 澄清一下,我说的是:“用于运行进程的原始访问令牌仍然可用。”是的,现在我们有两个 Windows 身份...我将编辑我的答案以包含一些关于如何切换回基础 Windows 帐户的示例代码。
      【解决方案4】:

      如果您担心哪个实体对您的应用程序有影响,首先要注意的是您的身份验证模式,例如(Windows、Form、Passport 或无)

      从读取的凭据中用于验证您的请求的位置取决于您为应用程序选择的验证模式。

      【讨论】:

        【解决方案5】:

        您不能将模拟部分与身份验证部分分开。我想你知道,因为你写了

        ...asp.net 自动模拟登录用户(如果不使用 Windows 身份验证,则模拟匿名帐户)...

        但我被这句话弄糊涂了

        为了便于讨论,我们假设身份是在 IIS 中设置的,而不是在 web.config 文件中。

        这到底是什么意思?

        但无论如何,让我试一试:
        假设您在 Web.config 中使用 IntegratedWindowsSecurity、<identity impersonate=true><authentication mode=Forms>。这将对应于您引用的Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication 中最后一个表的倒数第二行。

        它指出在这种情况下Domain\UserName 将从WindowsIdentity 返回。我假设你想知道Domain\UserName-Identity 来自哪里......使用 Kerberos 有一些限制,比如 IE 必须将 URL 分类为“Intranet”或“Local”,但我认为这在这里并不重要。

        现在区分在 Web.config 中设置 <authentication mode=windows> 和在 IIS 中将访问模式设置为 IntegratedWindowsSecurity(或其他任何名称)是很重要的。在上述链接的最后一个表中,我们处于将 IIS 设置为 IntegratedWindowsSecurity 的情况(尽管我们可以在 Web.config 中设置<authentication mode="windows">!)。因此 IE 与 IIS 协商如何验证当前登录的用户。使用 NTLM 或 Kerberos(主要取决于 Windows 版本)。这就是Domain\UserName 的来源。

        下面的文章(我知道是关于委托的)可能会更清楚地说明这个问题ASP.NET Delegation

        集成 Windows 身份验证

        当 Internet Explorer 尝试 访问受保护的资源,IIS 发送 两个 WWW-Authenticate 标头 浏览器、协商和 NTLM。这 协商标头仅由 IIS 发送 在 Windows 2000 或更高版本上运行。这 标头表示 IIS 支持 协商协议,它使 互联网之间发生的协商 Explorer 和 IIS 关于是否使用 Kerberos 或 NTLM 身份验证。 IIS 如果两个客户端都使用 Kerberos (Internet Explorer 5.0 及更高版本)和 服务器(IIS 5.0 及更高版本)正在运行 Windows 2000 或更高版本,两者都是 同一域或受信任的成员 域。否则,服务器 默认使用 NTLM。

        由于 NTLM 对用户进行身份验证 IIS 不提供用户的 IIS 的凭据,IIS 不能 将该用户的凭据委托给 远程机器。

        与 Kerberos 结合使用时 v5 身份验证,IIS 可以委托 计算机之间的安全凭证 运行 Windows 2000 或更高版本的 受信任并配置为委派。

        您可能知道这些链接,但我还是发布了它们:

        编辑:
        更准确地说,我 认为(此处不确定)IIS 使用解释的构造函数从 LogonToken(通过调用非托管 Win32 LogonUser 函数获得的)创建 WindowsIdentity here in msdnWindowsIdentity Class 文档中的示例代码也很有趣(例如IntPtrStringTypeConstructor)。那么登录令牌必须来自 IE。

        Scott Hanselman 也写过类似的文章:System.Threading.Thread.CurrentPrincipal vs. System.Web.HttpContext.Current.User or why FormsAuthentication can be subtle

        如果您寻找将自定义主体对象“植入”到 ASP.NET 身份验证过程中的解决方案(通常在Global.asax 中使用Application_AuthenticateRequest),我认为您可能能够提取更多信息。比如Using Custom Principal with Forms Authentication in ASP.NET

        或者您可以使用Reflector 自己查看:)

        【讨论】:

        • 您可以将身份验证和模拟分开,但您必须自己做,而不是使用 ASP.NET 配置。有关各种示例,请参阅本文:support.microsoft.com/kb/306158
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-08
        • 1970-01-01
        • 1970-01-01
        • 2010-09-22
        相关资源
        最近更新 更多