我正在尝试使用模拟测试一个ASP.NET MVC4 web应用程序,它同时与不同的用户连接。因此,测试的目的是执行几个驱动程序实例,每个实例都具有不同的模拟用户。听起来很简单..。
但是,如果在使用与当前用户不同的用户调用LogonUser之后,运行IEDriverServer,则会在启动时显示应用程序故障对话框。这是在EventLog中注册的信息:
Faulting application name: IEDriverServer.exe, version: 2.44.0.0, time stamp: 0x54496690
Faulting module name: IED7543.tmp, version: 0.0.0.0, time stamp: 0x5449668c
Exception code: 0xc0000005
Fault offset: 0x000000000009d609
Faulting process id: 0x760
Faulting application start time: 0x01d00e3d12f93475
Faulting application path: ...\bin\IEDriverServer.exe
Faulting module path: C:\Users\user\AppData\Local\Temp\IED7543.tmp
Report Id: 5383a54d-7a30-11e4-b39c-000c29b46927下面是我用来模拟的代码。它是基于我发现的所有例子,所以我没有意外.我们还尝试使用SimpleImpersonation分组,结果是相同的:
public class ImpersonationHelper
{
public enum LogonType
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
Cleartext = 8, // Win2K or higher
NewCredentials = 9 // Win2K or higher
};
public enum LogonProvider
{
Default = 0,
Winnt35 = 1,
Winnt40 = 2,
Winnt50 = 3
};
public enum ImpersonationLevel
{
SecurityAnonymous = 0,
SecurityIdentification = 1,
SecurityImpersonation = 2,
SecurityDelegation = 3
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel, ref IntPtr hNewToken);
public sealed class Impersonator : IDisposable
{
public string Domain { get; private set; }
public string User { get; private set; }
public string Password { get; private set; }
public LogonType Type { get; private set; }
public LogonProvider Provider { get; private set; }
private WindowsImpersonationContext _context;
private IntPtr _token;
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public Impersonator(string domain, string user, string password,
LogonType type = LogonType.Interactive,
LogonProvider provider = LogonProvider.Default)
{
Domain = domain;
User = user;
Password = password;
Type = type;
Provider = provider;
_token = IntPtr.Zero;
Logon();
}
public void Dispose()
{
Undo();
}
private void Logon()
{
try
{
if (!LogonUser(User, Domain, Password, (int)Type, (int)Provider, out _token))
{
int ret = Marshal.GetLastWin32Error();
throw new Exception(String.Format("LogonUser failed with error code : {0}", ret));
}
_context = WindowsIdentity.Impersonate(_token);
}
catch (Exception exception)
{
var message = exception.Message;
Undo();
}
}
private void Undo()
{
try
{
if (_token != IntPtr.Zero)
{
CloseHandle(_token);
_token = IntPtr.Zero; // Clean _token so Undo() could be called several times
}
if (_context != null)
{
_context.Undo();
_context = null; // Clean _context so Undo() could be called several times
}
}
catch (Exception exception)
{
var message = exception.Message;
// Releasing resources failed...
}
}
}
}引发异常的代码是:
using (new ImpersonationHelper.Impersonator("WIN-NKLTTMMUEPD", "tester", "tester"))
{
using (IWebDriver driver = new InternetExplorerDriver())
{
driver.Url = _appAddress;
return null;
}
}有人知道怎样才能防止这个错误出现吗?先谢谢你。
发布于 2014-12-17 06:28:43
我无法重现你的IEDriver崩溃。
然而,由于你已经在这个问题上投入了大量的精力,我并不介意花一点时间去寻找一个解决方案。我以前从未实现过Windows身份验证或需要测试模拟,但是我有UI自动化测试的经验。
时间被限制为一小时:
我不确定您是如何实现测试的,但是,我强烈建议您使用塞莱诺。它是Selenium驱动程序(您目前正在使用的)的包装器,但是它通过强制实现Page对象和Page组件以及使用强类型视图模型读取和写入Web页面数据的约定,使UI测试变得不那么痛苦/脆弱。
此外,我建议使用SimpleImpersonation库,因为它是Win32 API LogonUser函数的一个更安全/更干净的实现,例如它使用SafeHandle,而dispose path更干净。
我写的测试,
[Test]
public void GivenImpersonatedUser_IsLoggedInCorrectly()
{
const string domain = "domain"; // . for local machine
const string username = "impersonate.username";
const string password = "strongp@ssw0rd1";
const LogonType logonType = LogonType.Interactive;
using (Impersonation.LogonUser(domain, username, password, logonType))
{
var page = Host.Instance.NavigateToInitialPage<HomePage>();
Assert.That(page.LoginPanel.LoggedInUserName, Is.EqualTo(string.Format("{0}\\{1}", domain, username)));
}
}这是名为HomePage的Seleno对象,它使用可重用的组件LoginPanel。
public class HomePage : Page
{
public LoginPanel LoginPanel
{
get { return GetComponent<LoginPanel>(); }
}
}
public class LoginPanel : UiComponent
{
public string LoggedInUserName
{
get { return Find.Element(By.Id("login-username")).Text; }
}
}Seleno主机配置,使用IEDriver。
public static class Host
{
private static readonly InternetExplorerDriver Driver = new InternetExplorerDriver();
public static readonly SelenoHost Instance = new SelenoHost();
static Host()
{
Instance.Run(c =>
{
c.WithRemoteWebDriver(() => Driver);
c.ProjectToTest(new WebApplication(ProjectLocation.FromFolder("WebApplication1"), 61285));
c.UsingLoggerFactory(new ConsoleFactory());
c.UsingCamera("C:\\screenshots");
});
}
var codeBase = assembly.CodeBase;
var uri = new UriBuilder(codeBase);
var path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}我还学到了一些其他的东西:-如果你的用户名或密码不正确,你会得到错误代码1326。-您可以使用过程黑客来确认webdriver是用正确的身份验证令牌启动的。
正如我说的,我没有能够回答你的确切问题,但是尝试使用上面的和评论-很高兴进一步帮助。
https://stackoverflow.com/questions/27252713
复制相似问题