虽然禁用了模拟,但ASP.NET aspx页面代码仍会模拟

时间:2008-10-29 16:49:37

标签: asp.net authentication impersonation

我在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] Before1:当前的Princupal =   域\用户   [5288]之后:当前的Princupal =   域\用户

输出与

相同
<identity impersonate="false"/>

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

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

谢谢!

@Edit:Rob,谢谢你的提示! $ user快捷方式向我显示所有内容正如我所期望的那样:假冒我有进程运行用户NT AUTHORITY \ NETWORK SERVICE并且该线程在WindowsIdentity.Impersonate(IntPtr.Zero)之前有DOMAIN \ User和“No Token。Thread不冒充。“后。 但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;

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

3 个答案:

答案 0 :(得分:1)

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

  • 在监视窗口的Debug类型$ user中的断点处,它将显示进程和线程标识。
  • 您对模拟的使用不正确,请尝试以下代码:

    // 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();
        }
    }
    

答案 1 :(得分:1)

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

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

您是否在具有某些奇怪的本地政策的活动目录中?

答案 2 :(得分:1)

我想我在这里理解您的问题。

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

  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