将 ssl 证书添加到硒网络驱动程序

我使用硒与chromeDriver进行端到端测试。要测试的网站需要 SSL 证书。当我手动打开浏览器时,有一个弹出窗口,让我选择已安装的证书。不同的测试访问不同的 URL,并且还需要不同的证书。但是,如果我在无外设模式下运行测试,则不会弹出。因此,我需要一种方法来编程设置用于当前测试的证书(例如,设置文件)。.pem

我怎样才能做到这一点?我尝试设置一个浏览器Mob代理,然后将其配置为硒中的代理 - 但是,这似乎没有任何作用...有没有更好的方法?我做错了什么?以下是我尝试过的方法:

PemFileCertificateSource pemFileCertificateSource = new PemFileCertificateSource(
        new File("myCertificate.pem"),
        new File("myPrivateKey.pem"),
        "myPrivateKeyPassword");

ImpersonatingMitmManager mitmManager = ImpersonatingMitmManager.builder()
        .rootCertificateSource(pemFileCertificateSource)
        .build();

BrowserMobProxy browserMobProxy = new BrowserMobProxyServer();
browserMobProxy.setTrustAllServers(true);
browserMobProxy.setMitmManager(mitmManager);

browserMobProxy.start(8080);


ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setProxy(ClientUtil.createSeleniumProxy(browserMobProxy));

WebDriver webDriver = new ChromeDriver(chromeOptions);

// use the webdriver for tests, e.g. assertEquals("foo", webDriver.findElement(...))

答案 1

因此,开箱即用的浏览器Mob无法实现这一点。因此,我编写了一个代理扩展,可以插入Selenium并添加基于证书的身份验证以创建HTTPS连接。SeleniumSslProxy

这是它的工作原理:

  • 使用浏览器拦截硒 HTTP 请求Mob
  • 设置给定的证书(.pfx 文件)和密码SSLContext
  • 使用 okhttp 将请求转发到目标 URL
  • 将 okhttp 转换为 netty,以便 Selenium 可以处理ResponseFullHttpResponse

你可以在github上找到代码。下面是一个示例,如何在Selenium端到端测试中使用(也适用于无头模式):

@Before
public void setup() {
    ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    File clientSslCertificate = new File(
        classLoader.getResource("certificates/some-certificate.pfx").getFile());
    String certificatePassword = "superSecret";

    this.proxy = new SeleniumSslProxy(clientSslCertificate, certificatePassword);
    this.proxy.start();

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setProxy(proxy);
    this.webDriver = new ChromeDriver(chromeOptions);
}

@Test
public void pageTitleIsFoo() {
    // given
    String url = "http://myurl.lol";
    // NOTE: do not use https in the URL here. It will be converted to https by the proxy.

    // when
    this.webDriver.get(url);
    this.webDriver.manage().timeouts().implicitlyWait(5, SECONDS);

    // then
    WebElement title = this.webDriver.findElement(By.className("title"));
    assertEquals("Foo", title.getText());
}

@After
public void teardown() {
    this.webDriver.quit();
    this.proxy.stop();
}

请注意,我只使用chromeDriver,从未使用其他驱动程序进行测试。可能需要对 进行细微调整才能与其他驱动程序一起使用。SeleniumSslProxy


答案 2

推荐