【问题标题】:Watin Windows AuthenticationWatin Windows 身份验证
【发布时间】:2009-07-13 22:14:43
【问题描述】:

我正在尝试为使用集成身份验证的 Intranet 应用程序编写 Watin 测试。我尝试测试的网页打印 Page.User.Identity.Name。

这是我测试中的一些代码:

if (Win32.LogonUser(u.UserName, u.Domain, u.Password, 2 /*LOGON32_LOGON_INTERACTIVE*/, 0 /*LOGON32_PROVIDER_DEFAULT*/, out hToken))
            {
                if (Win32.DuplicateToken(hToken, 2, out hTokenDuplicate))
                {
                    WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate);
                    WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();  

                    Console.WriteLine(WindowsIdentity.GetCurrent().Name);

                    using (IE ie = new IE(url))
                    {
                        Console.WriteLine(ie.ContainsText(u.UserName));
                        ie.AutoClose = false;
                    }

                    impersonationContext.Undo();
                }
            }

当我运行此程序时,它会将我尝试模拟的用户名打印到控制台,但网页显示的是我当前登录的用户,而不是我应该模拟的用户。

在以下位置发现了类似问题:
Automated testing of authorization scenarios implemented with AzMan

【问题讨论】:

    标签: authentication watin


    【解决方案1】:

    模拟很棘手,我从来没有让 IE 作为 WatiN 的另一个用户上下文运行。过去,我已经部署了另一个版本的站点正在测试,启用了基本身份验证,然后通过对话框登录。

    查看以下博客了解更多信息和示例代码:

    http://blogs.msdn.com/jimmytr/archive/2007/04/14/writing-test-code-with-impersonation.aspx

    http://blogs.msdn.com/shawnfa/archive/2005/03/21/400088.aspx

    编辑:我今天得到了这个工作。诀窍是您需要将 IE 的启动和 IE 的自动化分开,因为您不能一键完成它们。

    首次启动,即使用 System.Diagnostics.Process。启动 IE 后,您可以使用来自here 的代码通过模拟附加并与 IE 对话

    这里是代码

        [TestMethod]
        public void TestMethod()
        {
            SecureString password = new SecureString();
            password.AppendChar('p');
            password.AppendChar('a');
            password.AppendChar('s');
            password.AppendChar('s');
            password.AppendChar('w');
            password.AppendChar('o');
            password.AppendChar('r');
            password.AppendChar('d');
    
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.UserName = "localtest";
            psi.Password = password;
            psi.UseShellExecute = false;
            psi.LoadUserProfile = true;
            psi.FileName = "c:\\Program Files\\Internet Explorer\\iexplore.exe";
            psi.Arguments = "about:blank";
    
            Process proc = new Process();
            proc.StartInfo = psi;
            proc.Start();
    
            t.Join();
    
            proc.Kill(); 
        }
    
        private static void DoWorkAs(object o)
        {
            User u = o as User;
    
    
            IntPtr hToken = IntPtr.Zero;
            IntPtr hTokenDuplicate = IntPtr.Zero;
    
            if (Win32.LogonUser(u.UserName, u.Domain, u.Password, 2 /*LOGON32_LOGON_INTERACTIVE*/, 0 /*LOGON32_PROVIDER_DEFAULT*/, out hToken))
            {
                if (Win32.DuplicateToken(hToken, 2, out hTokenDuplicate))
                {
                    WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate);
                    WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();
    
                    // domain\username
                    Console.WriteLine(" Thread 2 : " + WindowsIdentity.GetCurrent().Name);
    
                    IE ie = IE.AttachToIE(Find.ByUrl("about:blank"));
    
                    ie.GoTo(@"http://www.google.com/");
                    ie.TextField(Find.ByName("q")).TypeText("WatiN");
                    ie.Button(Find.ByName("btnG")).Click();
    
                    Assert.IsTrue(ie.ContainsText("WatiN"));
                    ie.GoTo("about:blank");
    
                    //revert
                    impersonationContext.Undo();
                    Console.WriteLine(WindowsIdentity.GetCurrent().Name);
                }
            }
            if (hToken != IntPtr.Zero) Win32.CloseHandle(hToken);
            if (hTokenDuplicate != IntPtr.Zero) Win32.CloseHandle(hTokenDuplicate);
        }
    
        public class User
        {
            public User(string u, string d, string p)
            {
                Domain = d;
                UserName = u;
                Password = p;
            }
            public string UserName;
            public string Domain;
            public string Password;
        }
        public class Win32
        {
            // P/Invoke snask
            [DllImport("advapi32.dll", SetLastError = true)]
            public static extern bool LogonUser(
                string lpszUsername,
                string lpszDomain,
                string lpszPassword,
                int dwLogonType,
                int dwLogonProvider,
                out IntPtr phToken);
    
            [DllImport("advapi32.dll", SetLastError = true)]
            public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int
               SECURITY_IMPERSONATION_LEVEL, out IntPtr DuplicateTokenHandle);
    
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool CloseHandle(IntPtr hHandle);
    
        }
    

    此代码需要重构,并且无法在带有 IE7 的 Vista 上运行,因为在 IE8 中修复了一个 IE 错误。

    【讨论】:

    • 谢谢布鲁斯。这给了我们一个解决方案,使我们能够继续前进。我希望看到 WatiN 在未来添加某种模拟支持。
    • 这里缺少一些代码吗? 't' 是在哪里定义的,你在哪里调用过 DoWorkAs()?
    • @Derek 我说代码需要重构。源代码包含在我的开源框架中testingstax.codeplex.com/SourceControl/changeset/view/…
    猜你喜欢
    • 2010-10-05
    • 2013-10-30
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2015-07-18
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多