2009-07-13 7 views
5

Ich versuche, Wattin-Tests für eine Intranet-Anwendung zu schreiben, die integrierte Authentifizierung verwendet. Die Webseite, die ich versuche zu testen, druckt Page.User.Identity.Name.Watin Windows-Authentifizierung

Hier ist ein Teil des Codes aus meinem Test:

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

Als ich dies ausführen, druckt es die Benutzername, die ich an die Konsole zu imitieren versuchen, aber die Web-Seite zeigt den Benutzer, dass ich Ich bin gerade eingeloggt als, nicht der Benutzer, den ich imitieren sollte.

ähnliches Problem gefunden bei:
Automated testing of authorization scenarios implemented with AzMan

Antwort

4

Identitätswechsel heikel ist, und ich habe nie in der Lage gewesen IE zu bekommen als einen anderen Benutzer Zusammenhang mit WatiN auszuführen. In der Vergangenheit habe ich eine andere Version der zu testenden Site mit aktivierter Basisauthentifizierung bereitgestellt und bin dann über den Dialog angemeldet.

Werfen Sie einen Blick auf die folgenden Blogs für weitere Informationen und Beispielcode:

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: Ich diese Arbeit heute habe. Der Trick ist, dass Sie den Start von IE und die Automatisierung von IE trennen müssen, da Sie sie nicht beide in einem Schlag tun können.

Zuerst starten, dh mit System.Diagnostics.Process. Sobald Sie IE gestartet haben, können Sie dann den Code aus here verwenden zu befestigen und hier auf IE impersionation

ist der Code

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

    } 

Dieser Code benötigt ein Refactoring und won'work auf Vista mit IE7 sprechen , wegen eines IE-Fehlers, der in IE8 behoben wurde.

+0

Danke Bruce. Dies gab uns eine Lösung, die es uns ermöglichte, voranzukommen. Ich würde es gerne sehen, dass WatiN in Zukunft eine Art Identitätswechsel-Unterstützung hinzufügen würde. –

+0

Fehlt hier ein Code? Wo ist 't' definiert und wo nennst du DoWorkAs()? –

+0

@Derek Ich sagte der Code benötigt einen Re-Faktor .. Die Quelle ist in meinem Open-Source-Framework hier enthalten http://testingstax.codeplex.com/SourceControl/changeset/view/6390#73028 –