Using Self-Signed SSL Certificates with Postman | Postman Blog

Using Self-Signed SSL Certificates with Postman | Postman Blog Сертификаты

Что было

1. JSON с данными

Using Self-Signed SSL Certificates with Postman | Postman Blog
Раньше тестовый набор хранился в таком виде

2. 2. Последовательность выполнения запросов с обработчиками на JS хранилась в коллекциях Postman.

Что стало

1. Тестовый набор переехал в Excel

Все данные вносятся в Excel (управляющие ключевые символы: R, H, I и т.д. распишу ниже) и дальше при помощи макроса перегоняются в json формат:

2. В Postman

Эксперимент проводил на стандартном наборе CRUD операций, который в дальнейшем можно расширять.

Так как в Postman все операций выполняются только в рамках запроса, пришлось ввести пустой get запрос в конце выполнения которого определяется следующий запрос из последовательности. Выполнить JS код до запроса и определить первый запрос без пустого не получилось.

Во всех запросах Pre-request script и Test секции пустые, весь код унифицирован для запросов и хранится в общих секциях Pre-request script и Test папки API Collection.

Во всех запросах важно обратить внимание на url и на секцию Body в запросах POST и PUT, их значения определяются переменными, значения в которые вносятся из JSON с данными.

Using self-signed ssl certificates with postman | postman blog


2020 Update: If you want to dig deeper into self-signed SSL certificates, check out our related post called Troubleshooting Self-Signed SSL Certificate Issues and More in Postman.


This post is applicable to the Postman Chrome app only. If you’re using the Mac app, head to our documentation for details on ignoring SSL errors.

Self-signed certificates are often used in testing and development environments to provide a layer of security for an API As they are not verified by a trusted authority, accessing  an API endpoint with something like https://<ip> through the Postman Chrome App, would throw up an error like this:

Screen Shot 2021-06-30 at 16.24.19

With the legacy app, you could go to the root URL in Chrome and allow the browser to access URLs with self-signed certificates. But this doesn’t work with the new packaged app. If you try to hit a URL with a self-signed SSL certificate, you would get a 500 error as Chrome would decline the certificate:

ssl_error

Turns out that there is a better solution to solve this a problem, and it also avoids adding an exception to Chrome every time you start the browser. This is how you do it:

  1. Go to the root URL in your browser. For ex. https://localhost
  2. Click on the lock icon on the top left in the URL bar.
  3. Open the Connection tab in the dropdown that comes up
  4. Click on certificate information

The dialog that comes up now depends on the operating system you are on. Chrome uses the underlying OS layer to handle SSL certificates.

Mac OS X

  1. In the dialog that comes up, click ‘View Certificate’, and drag the certificate icon to your desktop to create a *.cer file
    Screen Shot 2021-06-30 at 16.24.40
    Screen Shot 2021-06-30 at 16.24.46
    Using Self-Signed SSL Certificates with Postman | Postman Blog
  2. Double click on the file to open the OS X Keychain Access tool.
  3. Add the certificate to the System keychain and select “Always trust”
    Screen Shot 2021-06-30 at 16.30.05
  4. Once the certificate is added, double click it to open more details
  5. Expand the Trust item
  6. Select “Always trust”
    Screen Shot 2021-06-30 at 16.26.50
  7. Close Keychain Access and restart Chrome

Windows

  1. In the certificates window, go to the Details tab

ssl_win_2
2. Select Copy to File
3. Save the certificate file on your disk. Close the certificate window.

ssl_win_3
4. Go to Chrome > Settings, search for SSL (chrome://settings/search#ssl) and click on Manage certificates

ssl_win_4
5. Go to the Trusted Root Certification Authorities tab and click on import
6. Select the file you saved on your disk in step 3.

ssl_win_5
7. Close this window and restart Chrome.

Linux

  1. Go to the Details tab

ssl_linux_1
2. Select Export and save the file on your disk

ssl_linux_2
3. Go to Chrome > Settings, search for SSL (chrome://settings/search#ssl) and click on Manage certificates
4. Go into the Authorities tab

ssl_linux_3
5. Import the certificate
6. Restart Chrome

You should be able to fire requests to the endpoints validated by this certificate. The SSL warning will not show up in Chrome even if you restart the browser. Do make sure that you have verified the IP where the certificate comes from. This should only be done for verified IP addresses. This method also works for certificates for localhost. Make sure that the common name of the certificate while generating the certificate is localhost.

Про сертификаты:  Ответы на вопросы об ЭЦП | Удостоверяющий центр СберКорус

Let me know in the comments if you face any problems with this.

Для чего нужен postman?

Postman предназначен для проверки запросов с клиента на сервер и получения ответа от бэкенда. Можно описать общение Postman с бэкендом в виде диалога:

Postman: “Дай мне информацию по балансу именно этого пользователя”Backend: “Да, конечно, запрос правильный, получи информацию по балансу этого пользователя”

Такой позитивный диалог происходит в том случае, если ошибок на бэкенде нет и разработчик сделал всё согласно документации. Но не всегда это происходит в таком успешном ключе. В моей практике случались следующие диалоги:

Postman: “Дай мне информацию по балансу именно этого пользователя”Backend: “Кто я вообще?”

или

Postman: “Дай мне информацию по балансу именно этого пользователя”Backend: “Пользователь не найден.”

Описанные выше ответы от бэкенда имеют свой код ошибки, которые приходят в ответе.

В первом случае — это ошибка с кодом 500(Internal Server Error) внутренняя ошибка сервера, которая говорит о том, что сервер столкнулся с неожиданным условием, которое помешало ему выполнить запрос.

Запускаем

Using Self-Signed SSL Certificates with Postman | Postman BlogВсе 15 тестов прошли успешно, на картинке виден тест 14, в котором не вызывается Delete после POST

В тестах 1-11,13,15 после POST вызывается удаление созданного объекта:

История одного ssl рукопожатия

Привет, Хабр!

Недавно мне пришлось прикручивать SSL с двухсторонней аутентификацией (mutual authentication) к Spring Reactive Webclient. Казалось бы, дело нехитрое, но вылилось оно в блуждание в исходниках JDK с неожиданным финалом. Опыта набралось на целую статью, которая может оказаться полезной инженерам в повседневных задачах или при подготовке к собеседованию.

Есть REST-сервис на стороне заказчика, который работает через HTTPS.
Необходимо обращаться к нему из клиентского Java приложения.

Первое, что мне выдали в этом квесте, это 2 файла с расширением .pem — клиентский сертификат и приватный ключ. Я проверила их работоспособность с помощью Postman: указала пути к ним в настройках и, пульнув запрос, убедилась что сервер отвечает 200 OK и осмысленный response body. Отдельно проверила, что без клиентского сертификата сервер возвращает HTTP статус 500 и короткое сообщение в теле респонса, о том, что произошёл «Security exception» с определённым кодом.

Далее следовало правильно сконфигурировать клиентское Java приложение.

Для REST-запросов я использовала Spring Reactive WebClient с неблокирующим вводом-выводом.
В документации есть пример, как его можно кастомизировать, прокинув ему объект SslContext, который как раз хранит сертификаты и приватные ключи.

Моя конфигурация в упрощённом варианте была практически копипастой из документации:

SslContext sslContext = SslContextBuilder
	.forClient()
        .keyManager(…) /* Есть оверлоад, который принимает .pem файлы сертификата и приватного ключа (и, опционально, пароль). PEM файлы должны быть в определенной кодировке. Проверить/переконвертировать можно с помощью openssl утилиты.
 Альтернативно можно передать и KeyManagerFactory. */
	.build();
    
ClientHttpConnector connector = new ReactorClientHttpConnector(
            builder -> builder.sslContext(sslContext));

WebClient webClient = WebClient.builder()
            .clientConnector(connector).build();

Придерживаясь принципа TDD, я также написала тест, в котором вместо WebClient используется WebTestClient, выводящий кучу отладочной информации. Самый первый assertion был таким:

webTestClient
        .post()
        .uri([как называется эндпоинт])
        .body(BodyInserters.fromObject([тело запроса, в моём случае, обычная строка]))
        .exchange()
        .expectStatus().isOk()

Этот простой тест сразу же не прошёл: сервер вернул 500 с таким же body, как и в случае, если в Postman не указать клиентский сертификат.

Отдельно отмечу, что на время отладки, я включила опцию «не проверять серверный сертификат», а именно — передала инстанс InsecureTrustManagerFactory в качестве TrustManager для SslContext. Эта мера была избыточной, но исключала половину вариантов наверняка.

Отладочная информация в тесте не проливала свет на проблему, но выглядело всё, будто что-то пошло не так на этапе SSL handshake, поэтому я решила более подробно сравнить как происходит соединение в обоих случаях: для Postman и для Java клиента. Всё это можно посмотреть используя Wireshark — это такой популярный анализатор сетевого трафика. Заодно увидела как происходит SSL handshake с двухсторонней аутентификацией, так сказать, вживую (это очень любят спрашивать на собеседованиях):

  • Перво-наперво клиент отправляет сообщение Client Hello, содержащее метаинформацию вроде версии протокола и списка алгоритмов шифрования, которые он поддерживает
  • В ответ сервер отправляет сразу пачку следующих сообщений: Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done.
    В Server Hello указывается выбранный сервером алгоритм шифрования (cipher suite). Внутри Certificate лежит сертификат сервера. Server Key Exchange несёт в себе некоторую информацию, необходимую для шифрования, в зависимости от выбранного алгоритма (нас сейчас не интересуют детали, поэтому будем считать что это просто публичный ключ, хотя это некорректно!). Также, в случае двухсторонней аутентификации, в Certificate Request сообщении сервер делает запрос клиентского сертификата и поясняет, какие форматы он поддерживает и каким issuers доверяет.
  • Получив эту информацию, клиент проверяет сертификат сервера и отправляет свой сертификат, свой «публичный ключ», и другую информацию, в следующих сообщениях: Certificate, Client Key Exchange, Certificate Verify. Последним идёт ChangeCipherSpec сообщение, сигнализирующее о том, что всё дальнейшее общение будет происходить в зашифрованном виде
  • Наконец, после всех этих расшаркиваний, cервер проверят сертификат клиента и, если с ним всё в порядке, то отдаёт ответ.
Про сертификаты:  Как проверить SSL-сертификат

После пятнадцати минут втыкания в траффик, я заметила, что Java клиент в ответ на

Certificate Request

от сервера, по какой-то причине не отправляет свой сертификат, в отличие от Postman клиента. То есть, Certificate message есть, но он пустой.

Дальше мне нужно было бы посмотреть сначала в спецификацию протокола TLS, которая говорит буквально следующее:

If the certificate_authorities list in the certificate request message was non-empty, one of the certificates in the certificate chain SHOULD be issued by one of the listed CAs.

Речь идёт о списке certificate_authorities, указанном в

Certificate Request

message, приходящем от сервера. Клиентский сертификат (хотя бы один из цепочки) должен быть подписан одним из issuers, перечисленных в этом списке. Назовём это

проверкой X

.

Я об этом условии не знала и обнаружила его, когда дошла в отладке до глубин JDK (у меня это JDK9). Netty HttpClient, который лежит в основе Spring WebClient, использует по умолчанию SslEngine из JDK. Альтернативно можно переключить его на OpenSSL провайдер, добавив необходимые зависимости, но мне это, в конечном счёте, не потребовалось.
Итак, я расставила брейкпоинты внутри sun.security.ssl.ClientHandshaker класса и в хэндлере для serverHelloDone сообщения обнаружилась проверка X, которая не проходила: ни один из issuer-ов в цепочке клиентского сертификата не находился в списке issuer-ов, которым доверяет сервер (из Certificate Request message от сервера).

Я обратилась к заказчику за новым сертификатом, но заказчик возразил, что у него всё работает отлично, и вручил Python скрипт, которым он обычно проверял работоспособность сертификатов. Скрипт не делал ничего лишнего, кроме отправки HTTPS запроса с использованием Requests библиотеки, и возвращал 200 OK. Окончательно я удивилась, когда старый добрый curl тоже вернул 200 OK. Сразу вспомнился анекдот: «Вся рота идет не в ногу, один поручик шагает в ногу».

Curl — это, конечно, авторитетная утилита, но и TLS стандарт тоже не кусок туалетной бумаги. Не зная, что ещё можно проверить, я полезла бесцельно бродить по документации к curl, и на Github, где обнаружила вот такой известный баг.

Репортер описывал точь-в-точь проверку X: в curl с дефолтным бекэндом (OpenSSL) она не выполнялась, в отличие от curl с GnuTLS бекендом. Я не поленилась, собрала curl из исходников с опцией –with-gnutls, и отправила многострадальный реквест. И, наконец-то, ещё один клиент, кроме JDK, вернул HTTP статус 500 вместе с «Secutiry exception»!

Я написала об этом заказчику в ответ на аргумент «Ну curl-же работает» и получила новый сертификат, заново сгенеренный и аккуратно установленный на сервере. С ним моя конфигурация для WebClient заработала отлично. Happy End.

Эпопея с настройкой SSL заняла со всеми переписками больше двух недель (туда же вошло изучение подробных логов Java, ковыряние кода другого проекта, который у заказчика работает, и просто ковыряние в носу).

Что меня долго сбивало с толку, помимо разницы в поведении клиентов, так это то, что сервер был настроен таким образом, что сертификат запрашивал, но не проверял. Однако, и на это есть пояснения в спеке:

Про сертификаты:  Для чего нужен клиентский ssl сертификат | Защита информации

Also, if some aspect of the certificate chain was unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its discretion either continue the handshake (considering the client unauthenticated) or send a fatal alert.

Ключевые слова

R

– request, означает начало нового запроса, во второй ячейке строки хранится тип запроса, в третьей адрес, по которому надо обращаться. Обратите внимание, что в url можно указывать переменные Postman

Using Self-Signed SSL Certificates with Postman | Postman Blog
Значение из переменной подтянется

H – Данные для сверки в заголовке, пока ввел только response code, в Postman зашита проверка только на него. Важно чтобы в Excel название было таким же «response code», либо поправить в Postman

I, I2 … – Секция входных данных, поддерживает хранение моделей данных любой вложенности, цифра справа от I отвечает за уровень вложенности. Следующий набор данных вот так завернется в JSON. Если переменная, которая хранит данные пустая, то она не добавится.

Using Self-Signed SSL Certificates with Postman | Postman Blog
Данные этой секции будут поданы в теле запроса

O, O2 … — Секция выходных параметров, они будут сравнены с теми, что возвращает response. Как и секция Input поддерживает хранение моделей.

Using Self-Signed SSL Certificates with Postman | Postman Blog
При сравнении данные конвертируются в string, еще я дополнительно ограничил уровень рекурсии, это можно убрать

PO – Postman Output, значения из этой секции будут по имени переменной браться из response body запроса и записываться в переменную Postman.

Using Self-Signed SSL Certificates with Postman | Postman Blog
В Excel достаточно поставить любой символ, в переменную запишется значение из response, а не excelUsing Self-Signed SSL Certificates with Postman | Postman Blog
Эта секция нужна, чтобы хранить данные между скриптами, например чтобы удалить объект с id, который был создан в предыдущем реквесте

PC – Postman command, ввел только одну команду “terminate”, она используется для принудительного обрывания после выполнения текущего запроса. Полезно при негативном тесте, чтобы не вызывать шаг с удалением созданного объекта.

Using Self-Signed SSL Certificates with Postman | Postman Blog
Ввод этой команды позволил на одном листе хранить и позитивные и негативные тесты

PI – Postman Input, значения из этой секции будут записаны в переменные Postman перед определением url

Using Self-Signed SSL Certificates with Postman | Postman Blog
Может быть полезным, если надо переопределить переменные, которые указаны в url запроса.

Кстати, в подаваемых данных можно использовать данные из Postman переменных, для этого требуется использовать специальную конструкцию

В кейсе 1 мы внесли полученное значение в переменную, в кейсе 2 его использовали. Можно использовать не только в следующем кейсе, но и в текущем при следующем запросе. Например может потребоваться, если определение объекта для изменения идет не по url, а по значению переменной в запросе.

Подготовка к прогону

А теперь прогон, запускаем Postman runner, в нем выбираем нужную коллекцию и подгружаем файл с тестовыми данными:

Подавать будем следующий набор:

Здесь описано 15 тестов, при этом шаги 1-11, 13, 15 положительные с результатом 200 при POST запросе и шаги 12, 14 негативные с результатом 400. По ним информация в базу не будет внесена и поэтому секция Output пустая, а также указана команда terminate. Эта команда прервет выполнение последовательности и запрос на удаление «Delete» отправлен не будет.

После кейсов 1-11, 13, 15 мы запоминаем id который присвоился новому объекту, чтобы потом его удалить.

Ссылки

  1. Репозиторий на GitHub, там лежит Excel и коллекция Postman
  2. При разработке использовался VBA-JSON инструмент за авторством Tim Hall

Update от 15.10.2021

1. Доработал возможность генерации json файлов без запуска excel, выложил в гит GenerateAll.cmd, который запускает vb скрипт GenerateJsonFiles.vbs. Вызванный скрипт пройдет по текущей папке и всем вложенным и сгенерирует json файлы2. RunAll.cmd запускаем для прогона всех сгенерированных json файлов с данными, также пройдет текущую папку и все вложенные папки. Рядом с каждым из них положит output-report.log с результатами прогона.

Теперь прикрутить к CI не должно быть проблемой. Также можно прикрутить генерацию json к git deploy и проводить сравнение данных в excel по изменениях в json файлах.

Теперь о самих тестах

Using Self-Signed SSL Certificates with Postman | Postman Blog

Как читать Excel. Первой не пустой строкой идет номер тест кейса, то есть тест кейс хранится вертикально и на этой странице 9 тест кейсов. В текущем наборе в каждом тест кейсе будут выполнены сначала POST запрос, потом Delete.

Как запустить генерацию Json из Excel. В Excel нажать F11 и перейти на «ЭтаКнига», там запустить макрос.

Оцените статью
Мой сертификат
Добавить комментарий