加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-4 – IEDriverServer在使用模拟时引发错误

发布时间:2020-12-16 03:23:53 所属栏目:asp.Net 来源:网络整理
导读:我正在尝试使用模拟测试同时连接不同用户的ASP.NET MVC4 Web应用程序.因此,测试的想法是使用不同的模拟用户执行驱动程序的多个实例.听起来在概念上很容易…… 但是,如果在使用与当前用户不同的用户调用LogonUser后运行IEDriverServer,则会在启动时显示应用程
我正在尝试使用模拟测试同时连接不同用户的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: ...binIEDriverServer.exe
Faulting module path: C:UsersuserAppDataLocalTempIED7543.tmp
Report Id: 5383a54d-7a30-11e4-b39c-000c29b46927

这是我用于模仿的代码.它基于我找到的所有例子,所以我没有惊喜……我们也尝试使用SimpleImpersonation packege,结果相同:

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

有谁知道如何防止出现此错误?非常感谢你提前.

解决方法

我无法重现您的IEDriver崩溃.

但是,正如你对这个问题给予了赏金,我不介意花一点时间来寻找解决方案.我以前从未实现过Windows身份验证或需要测试模拟,但我有UI自动化测试的经验.

时间限制为一小时:

>创建了一个使用Windows身份验证的示例Intranet MVC应用程序;
>添加了一个新项目并设置了一个加载站点的基本单元测试.
>添加假冒.

我不确定你是如何实现你的测试的,但是我强烈建议你使用Seleno.我会强烈推荐你使用Seleno.它是Selenium Web Driver(你目前正在使用的)的包装器,但是它会进行UI测试通过强制实现页面对象和页面组件以及使用强类型视图模型读取和编写网页数据的约定来减少痛苦/脆弱.

另外我建议使用SimpleImpersonation库,因为它是Win32 API LogonUser功能的更安全/更清晰的实现,例如它使用SafeHandle并且配置路径更清洁.

我写的测试,

[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 Page对象,它使用可重用的Component 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.
– 您可以使用Process Hacker确认使用正确的身份验证令牌启动Webdriver进程.

正如我所说,我无法回答你确切的问题,但尝试使用上述内容并发表评论 – 乐意进一步提供帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读