如何使Selenium WebDriver动态选择客户端证书而不直观地检测弹出窗口

我正在尝试使用Java和Selenium来测试需要客户端证书的网站。当我浏览到我的网站时,我得到一个弹出窗口,如下所示,以选择正确的证书。

Windows Security: Select a Certificate

我的要求如下:

  • 按名称选择证书
  • 在不同版本的Windows / IE / Edge上

理想情况下,弹出窗口永远不会显示;也就是说,解决方案将涉及调用某些API或设置一些配置以固定要使用的正确证书。


我自己的解决方案理念:

  • 我尝试了一个基于使用SikuliX直观地检测正确证书的解决方案(它确实有效),但我想知道是否有更好的解决方案不依赖于视觉检测弹出窗口。在多个版本的Windows上不太可能失败,如果Microsoft决定更改此弹出窗口的外观,则这是未来的证明。

  • 我有另一个想法(但我不知道如何/是否可能)是删除除一个证书之外的所有已安装的证书,以便永远不会显示弹出窗口:

    • 备份整个存储
    • 删除 IE 可以使用的所有客户端证书(我需要的证书除外)
    • 执行不再需要选择任何证书的登录
    • 还原备份的存储

    有谁知道如何做到这一点(在Java中,可能调用CLI命令)?

  • 是否可以启动(使用Selenium Java)一个只知道我需要的单个证书的Internet Explorer Window?

  • 是否可以在 Internet Explorer 中为给定域设置默认证书?


答案 1

我们使用的解决方案非常干净,简单且可在浏览器和操作系统之间移植 - 使用代理服务器为您处理SSL握手。

您可以在测试运行的同一 JVM 中设置内存中人代理服务器,甚至可以在不同的端口上设置多个实例,每个实例分配给不同的客户端证书。然后,在创建 WebDriver 实例时,请使用适合您的浏览器的 setProxy 方法。请注意,浏览器将显示安装在代理本身(而不是目标服务器上)上的服务器证书,因此可能存在一些应在 WebDriver 设置中禁止显示的无效证书错误。或者 - 代理可以简单地使用有效的服务器证书,如果其密钥可供您使用,在这种情况下,连接对于测试脚本是完全透明的。

一个简单的代理服务器提供了Java中所需的功能,那就是LittleProxy。也许像BrowserMob这样的东西提供了一个更完整的解决方案,具有现成的API。

使用LittleProxy的示例只需要几行(几十行)样板:

步骤1:
使用客户端证书(例如p12文件或PEM文件)使用可以插入代码的内容来扩展类。在此存储库中公开提供的工作示例。org.littleshoot.proxy.MitmManager

步骤 2:
使用您选择的客户端证书和服务器证书启动代理服务器:

org.littleshoot.proxy.impl.DefaultHttpProxyServer.DefaultHttpProxyServer.bootstrap()
        .withIdleConnectionTimeout(FIVE_MINUTES)
        .withName(clientCertFile.getName())
        .withPort(port)
        .withAllowLocalOnly(localConnectionOnly)
        .withManInTheMiddle(new MutualAuthenticationCapableMitmManager(
                usingPKCS12File(clientCertFile, clientCertPassword),
                usingPemKeyPair(serverKeyPair[0], serverKeyPair[1])))
        .start();

为需要重用相同端口或通过 startnig 并发实例为每个客户端证书创建另一个代理。

步骤3:
使用代理启动WebDriver。主流浏览器(IE、Firefox、Chrome)也以类似的方式支持该设置:

org.openqa.selenium.Proxy proxy = new Proxy();
proxy.setSslProxy("127.0.0.1:5555");
proxy.setNoProxy("<-loopback>"); // overwrite the default no-proxy for localhost, 127.0.0.1

FirefoxOptions options = new FirefoxOptions();
options.setProxy(proxy);
WebDriver driver = new FirefoxDriver(options);

步骤4:
运行测试时,浏览器永远不会因任何证书提示而打扰您。利润。

如果使用这种技术,请格外小心,以确保机密的安全,特别是代理服务器本身对第三方无法访问。在安全的企业网络之外公开密钥从来都不是一个好主意,无论它们是真的(!!!)还是假的。


答案 2

我不能肯定地说,但如果硒不可能,我不会感到惊讶。

这个问题并没有让我充满希望:Selenium无法处理IE中的确认证书弹出窗口

你越远离网页,转向原生浏览器,然后是操作系统控制,硒就越无能为力。

正如链接问题的唯一答案所述:您可以在浏览器中禁用弹出窗口,这可能是也可能不是可行的解决方案。

如果你不想走这条路,人们通常会回到Java机器人来处理硒驱动程序无法做到的事情,例如与打印对话框和其他此类控件进行交互。

请参阅 mouseMove、mousePress、mouseRelease 你可以调用其中的每一个,为 mouseMove 提供按钮位置。https://docs.oracle.com/javase/7/docs/api/java/awt/Robot.html


推荐