2009-07-13 18 views
5

Próbuję napisać testy Watin dla aplikacji intranetowej, która używa zintegrowanego uwierzytelniania. Strona internetowa, którą próbuję przetestować, drukuje stronę .server.nazwa.nazwa.Watin Windows Authentication

Oto kod z mojego testu:

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

Kiedy uruchamiam to, wypisuje nazwę użytkownika, który staram się podszywać do konsoli, ale strona internetowa wyświetla użytkownikowi, że Jestem obecnie zalogowany jako nie użytkownik, któremu powinienem się podszywać.

Podobny problem znaleźć na stronie:
Automated testing of authorization scenarios implemented with AzMan

Odpowiedz

4

personifikacji jest trudne i nigdy nie byłem w stanie dostać się do pracy jako IE innym kontekście użytkownika z Watin. W przeszłości wdrożyłem inną wersję testowanej strony z włączonym podstawowym uwierzytelnianiem, a następnie zalogowałem się za pomocą okna dialogowego.

Wystarczy popatrzeć na następujących blogach o więcej informacji i próbki kodu:

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

Edit: Mam to już działa. Sztuką jest to, że musisz oddzielić uruchamianie IE i automatyzacji IE, ponieważ nie możesz zrobić tego po jednym uderzeniu.

Pierwsze uruchomienie, tj. Za pomocą System.Diagnostics.Process. Po uruchomieniu IE można następnie użyć kodu z here dołączyć i rozmawiać z IE przy użyciu impersionation

Oto kod

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

    } 

Ten kod wymaga Refactor i won'work na Vista z IE7 , z powodu błędu IE, który został naprawiony w IE8.

+0

Dzięki Bruce. To dało nam rozwiązanie, które pozwoliło nam ruszyć do przodu. Chciałbym zobaczyć, jak WatiN dodaje jakieś wsparcie personifikacji w przyszłości. –

+0

Czy jest tu jakiś kod? Gdzie jest zdefiniowane 't' i gdzie w ogóle nazywasz DoWorkAs()? –

+0

@Derek Powiedziałem, że kod wymaga ponownego współczynnika .. Źródło jest zawarte w mojej strukturze open source tutaj http://testingstax.codeplex.com/SourceControl/changeset/view/6390#73028 –