【问题标题】:ASP.NET aspx page code runs impersonated though impersonation is disabled尽管禁用了模拟,但 ASP.NET aspx 页面代码运行模拟
【发布时间】:2010-09-19 20:08:33
【问题描述】:

我在 VS 2005 中创建了一个空白测试应用程序作为 ASP.NET 应用程序。 MSDN says那个

默认情况下,ASP.NET 不使用模拟,您的代码使用 ASP.NET 应用程序的进程标识运行。

我有以下 web.config

<configuration>

    <appSettings/>
    <connectionStrings/>

    <system.web>
        <!-- 
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        -->
        <compilation debug="true" defaultLanguage="c#" />
        <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
        <authentication mode="Windows"/>
        <identity impersonate="false"/>
        <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
    </system.web>
</configuration>

因此,就像the article 建议的那样,模拟功能似乎已被禁用。

我的 aspx 默认为空白,代码隐藏为

namespace TestWebapp
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(String.Format("Before1: Current Princupal = {0}", Thread.CurrentPrincipal.Identity.Name));
            WindowsImpersonationContext ctx = WindowsIdentity.Impersonate(IntPtr.Zero);
            try
            {
                int a = 0;
                System.Diagnostics.Debug.WriteLine(String.Format("After: Current Princupal = {0}", Thread.CurrentPrincipal.Identity.Name));
            } finally
            {
                ctx.Undo();
            }

        }
    }
}

当我重新加载页面时,我得到以下调试输出:

[5288] 之前 1:当前原则 = 域\用户 [5288] 之后:当前校长 = 域\用户

输出与

相同
<identity impersonate="false"/>

该网站使用默认应用程序池,并且该池已设置为对其工作进程使用 NETWORK SERVICE 帐户。 我确定应用程序使用了它应该使用的 web.config,并且 w3p.exe 工作进程正在 NETWORK SERVICE 下运行。

在这种情况下会出现什么问题?

谢谢!

@Edit:Rob,谢谢你的提示! $user 快捷方式告诉我一切都在按我的预期发生:通过模拟,我有运行用户 NT AUTHORITY\NETWORK SERVICE 的进程,并且线程在 WindowsIdentity.Impersonate(IntPtr.Zero) 和“No Token.Thread”之前具有 DOMAIN\User不冒充。”后。 但是 Thread.CurrentPrincipal.Identity.Name 和 HttpContext.Current.User.Identity.Name 在这两个地方仍然给我 DOMAIN\User。

@Edit:我发现要更改 Thread.CurrentPrincipal 和 HttpContext.Current.User 我必须手动进行:

Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
HttpContext.Current.User = Thread.CurrentPrincipal;

我不确定这里有什么意义,但无论如何。我现在对 sharepoint 共享服务管理用户配置文件权限有疑问,但这是另一个问题。

【问题讨论】:

    标签: asp.net authentication impersonation


    【解决方案1】:

    看起来很奇怪,有几件事要尝试:

    • 在 Debug 中的断点处,在监视窗口中键入 $user,这将显示进程和线程标识。
    • 你对impersonate的使用不正确,试试这个代码:

      // Declare the logon types as constants
      const long LOGON32_LOGON_INTERACTIVE = 2;
      const long LOGON32_LOGON_NETWORK = 3;
      
      // Declare the logon providers as constants
      const long LOGON32_PROVIDER_DEFAULT = 0;
      const long LOGON32_PROVIDER_WINNT50 = 3;
      const long LOGON32_PROVIDER_WINNT40 = 2;
      const long LOGON32_PROVIDER_WINNT35 = 1;
      
      [DllImport("advapi32.dll", EntryPoint = "LogonUser")]
      private static extern bool LogonUser(
          string lpszUsername,
          string lpszDomain,
          string lpszPassword,
          int dwLogonType,
          int dwLogonProvider,
          ref IntPtr phToken);
      
      public static WindowsImpersonationContext ImpersonateCurrentUserBegin(System.Net.NetworkCredential credential)
      {
          WindowsImpersonationContext impersonationContext = null;
          if (credential == null || credential.UserName.Length == 0 || credential.Password.Length == 0 || credential.Domain.Length == 0)
          {
              throw new Exception("Incomplete user credentials specified");
          }
          impersonationContext = Security.Impersonate(credential);
          if (impersonationContext == null)
          {
              return null;
          }
          else
          {
              return impersonationContext;
          }
      }
      
      public static void ImpersonateCurrentUserEnd(WindowsImpersonationContext impersonationContext)
      {
          if (impersonationContext != null)
          {
              impersonationContext.Undo();
          }
      }
      

    【讨论】:

    • 感谢有关 $user 的提示。对于 $user 它表明(我现在有 )一切都如我所料。 WindowsIdentity.Impersonate(IntPtr.Zero)之前有被冒充用户的token,之后没有token,进程在NETWORK SERVICE下
    • 但是 System.Threading.Thread.CurrentPrincipal.Identity.Name 和 HttpContext.Current.User.Identity.Name 仍然给我模拟用户。
    【解决方案2】:

    HttpContext.User.Identity.Name 给你什么?

    假设您已检查 IIS 中的安全选项卡是否允许匿名访问?

    您是否在一个有一些奇怪的本地策略的活动目录中?

    【讨论】:

    • HttpContext.User.Identity.Name 与 Thread.CurrentPrincipal.Identity.Name 的结果相同,允许匿名访问也一样。
    • 我不知道域策略,必须尝试在另一个域中进行。
    【解决方案3】:

    我想我明白你的问题了。

    在继续前进之前要了解的事情,

    1. 应用程序运行时存在不同的安全上下文。比如System.Security.Principal.WindowsIdentity.GetCurrent().Name,还有你上面提到的System.Threading.Thread.CurrentPrincipal.Identity.Name

    2. 在 Web 应用程序中,System.Threading.Thread.CurrentPrincipal.Identity 始终由 HttpContext.Current.User.Identity 提供。

    说到你的意思。如果你想修改System.Threading.Thread.CurrentPrincipal.Identity,那么修改你的认证机制最初提供的HttpContext.Current.User.Identity

    【讨论】:

      猜你喜欢
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 2022-06-14
      • 2015-05-03
      相关资源
      最近更新 更多