2009-07-13 220 views
5

我正在嘗試爲使用集成身份驗證的Intranet應用程序編寫Watin測試。我試圖測試的網頁打印Page.User.Identity.Name。Watin Windows身份驗證

下面是一些從我的測試代碼:

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

回答

4

模擬是棘手的,我從來沒有能夠得到IE瀏覽器與華廷另一個用戶上下文中運行。在過去,我已經部署了另一個正在測試的站點,並啓用了基本身份驗證,然後通過對話框登錄。

看一看更多的信息和示例代碼以下博客:

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與IE7附加和使用impersionation

這裏是代碼

[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); 

    } 

此代碼需要重構跟IE,並won'work在Vista ,因爲在IE8中修復了一個IE bug。

+0

謝謝布魯斯。這給了我們一個讓我們前進的解決方案。我希望看到WatiN將來會添加某種模擬支持。 – 2009-07-14 22:30:29