2009-07-13 9 views
5

J'essaie d'écrire des tests Watin pour une application intranet qui utilise l'authentification intégrée. La page Web que j'essaie de tester imprime Page.User.Identity.Name.Authentification Windows Watin

Voici une partie du code de mon 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(); 
       } 
      } 

Quand je lance cela, il imprime le nom d'utilisateur que je suis en train de faire passer à la console, mais la page Web affiche l'utilisateur que je Je suis actuellement connecté en tant que, pas l'utilisateur que je devrais usurper l'identité.

problème similaire à l'adresse:
Automated testing of authorization scenarios implemented with AzMan

Répondre

4

Impersonation est délicate et je n'ai jamais été en mesure d'obtenir IE pour exécuter un autre contexte utilisateur avec Watin. Dans le passé, j'ai déployé une autre version du site testé avec l'authentification de base activée, puis connecté via la boîte de dialogue.

Jetez un oeil sur les blogs suivants pour plus d'informations et des exemples de code:

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: Je suis arrivé aujourd'hui à travailler. l'astuce est que vous devez séparer le lancement de IE et l'automatisation de IE car vous ne pouvez pas les faire tous les deux en un seul coup.

Premier lancement c'est-à-dire en utilisant System.Diagnostics.Process. Une fois que vous avez lancé IE vous pouvez utiliser le code de here pour attacher et parler à IE en utilisant impersionation

Voici le 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); 

    } 

Ce code a besoin d'un refactoring et won'work sur Vista avec IE7 , à cause d'un bug IE qui a été corrigé dans IE8.

+0

Merci Bruce. Cela nous a donné une solution qui nous a permis d'aller de l'avant. Je voudrais voir WatiN ajouter une sorte de soutien d'usurpation d'identité à l'avenir. –

+0

Y at-il un code manquant ici? Où est 't' défini et où appelez-vous jamais DoWorkAs()? –

+0

@Derek J'ai dit que le code avait besoin d'un re-facteur. La source est incluse dans mon framework open source ici http://testingstax.codeplex.com/SourceControl/changeset/view/6390#73028 –

Questions connexes