Добавить ssl-сертификат в selenium-webdriver

Я использую селен для сквозного тестирования с chromeDriver. Веб-сайты для тестирования требуют сертификат ssl. Когда я вручную открываю браузер, появляется всплывающее окно, которое позволяет мне выбрать установленный сертификат. Разные тесты обращаются к разным URL-адресам и требуют разных сертификатов. Однако, если я запускаю тесты в автономном режиме, всплывающее окно не появляется. Поэтому мне нужен способ программно установить сертификат (например, установить файл .pem), который будет использоваться для текущего теста.

Как я могу этого добиться? Я попытался настроить прокси-сервер browserMob, который затем настроил как прокси-сервер в селене, однако это не так. кажется, ничего не делает... Есть ли лучшие подходы? Что я делаю неправильно? Вот что я пробовал:

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(...))

person Tagas    schedule 07.05.2019    source источник
comment
Посетите stackoverflow.com/q/6774235/3141682.   -  person Adi Ohana    schedule 07.05.2019
comment
@AdiOhana Я уже довольно тщательно искал ТАК ... Человек в этой ссылке просто описывает, как избежать ошибки ненадежного сертификата - это не то, что я хочу, мне нужно программно установить сертификат для использования.   -  person Tagas    schedule 07.05.2019
comment
правильно, но один из ответов описывает: вы можете указать браузеру Chrome использовать определенный клиентский сертификат для определенного URL-адреса, добавив КЛЮЧ реестра со следующим содержимым: это то, что вы ищете?   -  person Adi Ohana    schedule 07.05.2019
comment
Не совсем... Немного грязно вносить изменения в реестр для каждого теста. Кроме того, в какой-то момент я хотел бы запустить эти тесты в контейнерах докеров, так что это больше не будет возможно.   -  person Tagas    schedule 07.05.2019
comment
Можно было бы работать в контейнерах докеров, если вы создадите новый драйвер (и браузер) для каждого из ваших тестовых случаев с желаемым сертификатом в соответствии с вашим веб-сайтом.   -  person Adi Ohana    schedule 10.05.2019


Ответы (1)


Очевидно, это невозможно с BrowserMob из коробки. Поэтому я написал прокси-расширение SeleniumSslProxy, которое можно подключить к Selenium и добавить аутентификацию на основе сертификата для создания HTTPS-соединения.

Вот как это работает:

  • перехватывать HTTP-запросы Selenium с помощью BrowserMob
  • настроить SSLContext с сертификатом (файл .pfx) и паролем
  • используйте https://github.com/square/okhttp, чтобы перенаправить запрос на целевой URL
  • преобразовать okhttp Response в netty FullHttpResponse, чтобы его можно было обрабатывать с помощью Selenium

Вы можете найти код на 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 могут потребоваться для использования с другими драйверами.

person Tagas    schedule 16.05.2019