2009-07-13 13 views
5

Sto provando a scrivere i test Watin per un'applicazione Intranet che utilizza l'autenticazione integrata. La pagina Web che sto tentando di testare stampa Page.User.Identity.Name.Watin Autenticazione Windows

Ecco parte del codice dal mio 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(); 
       } 
      } 

Quando ho eseguito questo, stampa il nome utente che sto cercando di impersonare alla console, ma la pagina Web visualizza l'utente che ho sono attualmente loggato come, non l'utente che dovrei impersonare.

problema simile disponibile all'indirizzo:
Automated testing of authorization scenarios implemented with AzMan

risposta

4

rappresentazione è ingannevole e non sono mai stato in grado di ottenere IE per l'esecuzione come un altro contesto utente con WatiN. In passato ho implementato un'altra versione del sito in fase di test con l'autenticazione di base abilitata e quindi l'accesso tramite la finestra di dialogo.

Date un'occhiata ai seguenti blog per ulteriori informazioni e codice di esempio:

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: ho ottenuto questo oggi a lavorare. il trucco è che è necessario separare il lancio di IE e l'automazione di IE in quanto non è possibile eseguirli entrambi in un colpo solo.

Primo avvio, ovvero utilizzando System.Diagnostics.Process. Una volta avviato Internet Explorer è possibile utilizzare il codice da here attaccare e parlare con IE utilizzando impersionation

Ecco il codice

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

    } 

Questo codice ha bisogno di un refactoring, e won'work su Vista con IE7 , a causa di un bug di IE corretto in IE8.

+0

Grazie Bruce. Questo ci ha dato una soluzione che ci ha permesso di andare avanti. Mi piacerebbe vedere WatiN aggiungere una sorta di supporto alla rappresentazione in futuro. –

+0

C'è del codice mancante qui? Dove viene definito 't' e dove si chiama DoWorkAs()? –

+0

@Derek Ho detto che il codice aveva bisogno di un rifacimento. La fonte è inclusa nel mio framework open source qui http://testingstax.codeplex.com/SourceControl/changeset/view/6390#73028 –