Это руководство посвящено настройке защиты приложений с помощью TLS-аутентификации. При таком подходе возможность работы пользователей с приложением зависит от имеющихся у них сертификатов. То есть — разработчик может самостоятельно принимать решения о том, каким пользователям разрешено обращаться к приложению.
В учебном проекте, который будет здесь разобран, показаны основные настройки сервера и клиента. Их взаимодействие изначально осуществляется посредством HTTP. А это значит, что данные между ними передаются в незашифрованном виде. Наша задача заключается в том, чтобы обеспечить шифрование всего того, чем обмениваются клиент и сервер.
Мы рассмотрим следующие вопросы:
В данном проекте содержится Maven-обёртка, поэтому запустить его можно и не устанавливая Maven. Тут будут приведены сведения и о стандартных командах, рассчитанных на mvn, и о командах, ориентированных на использование Maven-обёртки.
Если вы хотите запустить этот проект с использованием Java 8 — вы можете переключиться на более старую его версию с использованием нижеприведённой команды.
При работе с этой версией проекта рекомендовано следовать инструкциям, подготовленным специально для него. Найти их можно здесь.
Сервер можно привести в рабочее состояние, вызвав метод main класса App или выполнив следующую команду в корневой директории проекта:
Вот команда, рассчитанная на Maven-обёртку:
Сейчас сервер работает на порте, используемом по умолчанию (8080) без шифрования. С помощью следующей команды, задействующей curl, можно обратиться к конечной точке hello:
Ответ должен выглядеть примерно так:
Обратиться к серверу можно и с использованием клиента, код которого находится в директории client. Клиент зависит от других компонентов проекта. Поэтому, прежде чем его запускать, нужно выполнить в корневой директории проекта команду mvn install или ./mvnw install.
В клиенте реализован интеграционный тест, основанный на Cucumber. Его можно запустить, обратившись к классу ClientRunnerIT из IDE, или выполнив в корневой директории следующую команду:
При использовании Maven-обёртки это будет такая команда:
Тут имеется файл Hello.feature, который описывает шаги интеграционного теста. Этот файл можно найти в папке ресурсов теста клиентского проекта.
Есть и другой метод запуска и клиента, и сервера. Он представлен следующей командой, выполняемой в корневой директории проекта:
Вариант этой команды для Maven-обёртки выглядит так:
Клиент, по умолчанию, отправляет запросы к localhost, так как он рассчитан на то, что сервер выполняется на том же компьютере, что и он сам. Если сервер работает на другой машине — соответствующий URL можно передать клиенту при запуске, воспользовавшись следующим аргументом VM:
Теперь давайте разберёмся с тем, как защитить сервер с помощью TLS. Сделать это можно, добавив соответствующие свойства в файл application.yml, хранящий настройки приложения.
Речь идёт о следующих настройках:
Возможно, тут у вас появится вопрос о причинах изменения номера порта сервера на 8443. Дело в том, что tomcat-серверы, поддерживающие HTTPS, принято размещать на порте 8443. А серверы, поддерживающие HTTP — на порте 8080. Поэтому при настройке подобного соединения можно использовать и порт 8080, но поступать так не рекомендуется. Тут можно почитать подробности о том, какие номера портов используются в разных ситуациях.
Для того чтобы вышеописанные настройки вступили в силу — сервер надо перезапустить. Возможно, при этом вы увидите следующее исключение:
Причина его появления заключается в том, что серверу, для установки защищённого соединения с внешними сущностями, нужно хранилище ключей с сертификатом сервера. Сервер может предоставить более подробную информацию об этом в том случае, если воспользоваться следующими аргументами VM:
Для того решения этой проблемы нужно создать хранилище ключей, содержащее открытый и закрытый ключи для сервера. Открытый ключ будет передаваться пользователям. Так они смогут зашифровать данные, передаваемые серверу. Зашифрованные данные могут быть расшифрованы с использованием закрытого ключа сервера. Закрытый ключ сервера нельзя никому передавать, так как, имея этот ключ, злоумышленник может перехватить зашифрованные данные, которыми обмениваются клиент и сервер, и расшифровать их.
Создать хранилище ключей с открытым и закрытым ключами можно с помощью следующей команды:
Теперь нужно сообщить серверу о том, где именно находится хранилище ключей, и указать пароли. Сделаем это, отредактировав наш файл application.yml:
Замечательно! Только что мы настроили TLS-шифрование соединений между сервером и клиентом! Испытать сервер можно так:
Клиент можно запустить и прибегнув к классу ClientRunnerIT.
В результате можно будет увидеть следующее сообщение:
Возникает такое ощущение, что клиент пытается поприветствовать сервер, а сервер ему найти не удаётся. Проблема заключается в том, что клиент пытается обратиться к серверу, работающему на порте 8080, а сервер ждёт запросов на порте 8443. Исправим это, внеся некоторые изменения в класс Constants. А именно — найдём эту строку:
И приведём её к такому виду:
Попробуем снова запустить клиент. Это приведёт к выдаче такого сообщения:
Дело тут в том, что клиент собирается наладить обмен данными по HTTPS. Он, при выполнении процедуры рукопожатия, получает сертификат сервера, который он пока не может распознать. А это значит, что нам ещё нужно создать хранилище TrustStore. В таких хранилищах находятся доверенные сертификаты. Клиент сопоставляет то, что он получает в ходе процедуры рукопожатия, с тем, что есть в TrustStore. Если полученный им сертификат входит в список доверенных сертификатов — процедура продолжается. А прежде чем создавать TrustStore — нужно обзавестись сертификатом сервера.
Экспортировать сертификат сервера можно такой командой:
Теперь можно создать TrustStore для клиента и импортировать туда сертификат сервера такой командой:
TrustStore для клиента мы создали, но сам клиент пока об этом не знает. А это значит, что клиенту надо сообщить о том, что ему следует пользоваться TrustStore, указав адрес хранилища и пароль. Клиенту надо сообщить и о том, что включена аутентификация. Всё это делается путём приведения файла application.yml клиентского приложения к такому виду:
Следующий шаг нашей работы заключается такой настройке сервера, чтобы он требовал бы аутентификации клиентов. Благодаря этим настройкам мы принудим клиентов идентифицировать себя. При таком подходе сервер тоже сможет проверить подлинность клиента, и то, входит ли он в число доверенных сущностей. Включить аутентификацию клиентов можно, воспользовавшись свойством client-auth, сообщив серверу о том, что ему нужно проверять клиентов.
Приведём файл сервера application.yml к такому виду:
Если после этого запустить клиент, то он выдаст следующее сообщение об ошибке:
Это указывает на то, что клиент не обладает подходящим сертификатом. Точнее — у клиента пока вообще нет сертификата. Поэтому создадим сертификат следующей командой:
Нам ещё нужно создать TrustStore для сервера. Но, прежде чем создавать это хранилище, нужно иметь сертификат клиента. Экспортировать его можно так:
Теперь создадим TrustStore сервера, в котором будет сертификат клиента:
Мы создали для клиента дополнительное хранилище ключей, но клиент об этом не знает. Сообщим ему сведения об этом хранилище. Кроме того, клиенту нужно сообщить о том, что включена двусторонняя аутентификация.
Приведём файл application.yml клиента к такому виду:
Сервер тоже не знает о только что созданном для него TrustStore. Приведём его файл application.yml к такому виду:
Если снова запустить клиент — можно будет убедиться в том, что тест завершается успешно, и что клиент получает данные от сервера в защищённом виде.
Примите поздравления! Только что вы настроили двусторонний TLS!
Есть и другой способ организации двусторонней аутентификации. Он основан на использовании доверенного удостоверяющего центра. У такого подхода есть сильные и слабые стороны.
Сильные стороны:
Обычно работают с уже существующими удостоверяющими центрами, которым, для подписи, нужно передавать сертификаты. Здесь же мы создадим собственный удостоверяющий центр и подпишем с его помощью сертификаты клиента и сервера. Для создания удостоверяющего центра воспользуемся такой командой:
Ещё можно воспользоваться существующим удостоверяющим центром.
Для того чтобы подписать сертификат — нужен .csr-файл (Certificate Signing Request, файл запроса на подпись сертификата). Создать его можно с помощью особой команды.
Вот её вариант для сервера:
Вот — эта команда для клиента:
Такой файл нужен удостоверяющему центру для подписи сертификата. Следующий шаг нашей работы заключается в подписании сертификата.
Вот соответствующая команда для клиента:
Вот команда для сервера:
В хранилище идентификационных данных сервера и клиента всё ещё хранится неподписанный сертификат. Сейчас можно заменить его на подписанный. У инструмента keytool есть одна не вполне понятная особенность. А именно — он не позволяет напрямую импортировать в хранилище подписанный сертификат. Если попытаться это сделать — будет выведено сообщение об ошибке. Сертификат, подписанный удостоверяющим центром, должен быть представлен в файле identity.jks.
Экспортируем подписанный сертификат:
Выполним на клиенте следующие команды:
На сервере выполним такие команды:
Теперь нужно настроить клиент и сервер так, чтобы они доверяли бы только удостоверяющему центру. Сделать это можно, импортировав сертификат удостоверяющего центра в хранилища TrustStore клиента и сервера.
Сделаем это, выполнив на клиенте следующую команду:
На сервере выполним такую команду:
В хранилищах TrustStore всё ещё хранятся собственные сертификаты клиента и сервера. Эти сертификаты нужно удалить.
Выполним на клиенте такую команду:
Вот — команда для сервера:
Если снова запустить клиент — можно видеть успешное прохождение теста. А это значит, что клиент и сервер успешно обмениваются данными, используя сертификаты, подписанные удостоверяющим центром.
Всё, о чём мы говорили выше, можно автоматизировать с помощью скриптов, которые находятся в папке script рассматриваемого нами проекта. Для запуска скриптов можете воспользоваться следующими командами:
Ниже приведён список протестированных клиентов. Настройки для HTTP-клиента, написанного на чистом Java, можно найти в классе ClientConfig. В директории service нашего проекта содержатся отдельные HTTP-клиенты, выполняющие демонстрационные запросы. Настройки HTTP-клиентов, основанных на Kotlin и Scala, включены в состав проекта в виде вложенных классов. Все примеры клиентов используют одну и ту же базовую конфигурацию SSL, созданную в классе SSLConfig.
Java:
Kotlin:
Scala:
Автор оригинала: Hakan Altındağ
https://dzone.com/articles/hakky54mutual-tls-1
В учебном проекте, который будет здесь разобран, показаны основные настройки сервера и клиента. Их взаимодействие изначально осуществляется посредством HTTP. А это значит, что данные между ними передаются в незашифрованном виде. Наша задача заключается в том, чтобы обеспечить шифрование всего того, чем обмениваются клиент и сервер.
Мы рассмотрим следующие вопросы:
- Запуск сервера
- Отправка приветствия серверу (без шифрования)
- Включение HTTPS на сервере (односторонний TLS)
- Аутентификация клиента (двусторонний TLS)
- Установление двустороннего TLS-соединения с использованием доверенного удостоверяющего центра.
- Автоматизация различных подходов к аутентификации
- Идентификационные данные объекта: хранилище KeyStore, хранящее пару ключей — закрытый (private) и открытый (public).
- TrustStore: хранилище KeyStore, содержащее один или большее количество сертификатов (открытых ключей). Это хранилище содержит список доверенных сертификатов. Оно хранит данные о приложениях, которым доверяет наше приложение.
- Односторонняя аутентификация (односторонний TLS, односторонний SSL): HTTPS-соединение, при установке которого клиент проверяет сертификат противоположной стороны.
- Двусторонняя аутентификация (двусторонний TLS, двусторонний SSL, взаимная аутентификация): HTTPS-соединение, при установке которого клиент и противоположная сторона проверяют сертификаты друг друга.
1. Запуск сервера
Для того чтобы организовать работу сервера — нам понадобится следующее:- Java 11
- Maven 3.5.0
- Eclipse, Intellij IDEA (или любой другой текстовой редактор вроде VIM)
- Доступ к терминалу
- Копия этого проекта
В данном проекте содержится Maven-обёртка, поэтому запустить его можно и не устанавливая Maven. Тут будут приведены сведения и о стандартных командах, рассчитанных на mvn, и о командах, ориентированных на использование Maven-обёртки.
Если вы хотите запустить этот проект с использованием Java 8 — вы можете переключиться на более старую его версию с использованием нижеприведённой команды.
Код:
git checkout tags/java-8-compatible
Сервер можно привести в рабочее состояние, вызвав метод main класса App или выполнив следующую команду в корневой директории проекта:
Код:
cd server/ && mvn spring-boot:run
Код:
cd server-with-spring-boot/ && ./../mvnw spring-boot:run
2. Отправка приветствия серверу (без шифрования)
Сейчас сервер работает на порте, используемом по умолчанию (8080) без шифрования. С помощью следующей команды, задействующей curl, можно обратиться к конечной точке hello:
Код:
curl -i -XGET http://localhost:8080/api/hello
Код:
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 5
Date: Sun, 11 Nov 2018 14:21:50 GMT
Hello
В клиенте реализован интеграционный тест, основанный на Cucumber. Его можно запустить, обратившись к классу ClientRunnerIT из IDE, или выполнив в корневой директории следующую команду:
Код:
cd client/ && mvn exec:java
Код:
cd client/ && ./../mvnw exec:java
Есть и другой метод запуска и клиента, и сервера. Он представлен следующей командой, выполняемой в корневой директории проекта:
Код:
mvn clean verify
Код:
./mvnw clean verify
Код:
-Durl=http://[HOST]:[PORT]
3. Включение HTTPS на сервере (односторонний TLS)
Теперь давайте разберёмся с тем, как защитить сервер с помощью TLS. Сделать это можно, добавив соответствующие свойства в файл application.yml, хранящий настройки приложения.
Речь идёт о следующих настройках:
Код:
server:
port: 8443
ssl:
enabled: true
Для того чтобы вышеописанные настройки вступили в силу — сервер надо перезапустить. Возможно, при этом вы увидите следующее исключение:
Код:
IllegalArgumentException: Resource location must not be null
Код:
-Djavax.net.debug=SSL,keymanager,trustmanager,ssl:handshake
Создать хранилище ключей с открытым и закрытым ключами можно с помощью следующей команды:
Код:
keytool -v -genkeypair -dname "CN=Hakan,OU=Amsterdam,O=Thunderberry,C=NL" -keystore shared-server-resources/src/main/resources/identity.jks -storepass secret -keypass secret -keyalg RSA -keysize 2048 -alias server -validity 3650 -deststoretype pkcs12 -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1
Код:
server:
port: 8443
ssl:
enabled: true
key-store: classpath:identity.jks
key-password: secret
key-store-password: secret
Код:
curl -i --insecure -v -XGET https://localhost:8443/api/hello
В результате можно будет увидеть следующее сообщение:
Код:
java.net.ConnectException: Connection refused (Connection refused)
Код:
private static final String DEFAULT_SERVER_URL = "http://localhost:8080";
Код:
private static final String DEFAULT_SERVER_URL = "https://localhost:8443";
Код:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Экспортировать сертификат сервера можно такой командой:
Код:
keytool -v -exportcert -file shared-server-resources/src/main/resources/server.cer -alias server -keystore shared-server-resources/src/main/resources/identity.jks -storepass secret -rfc
Код:
keytool -v -importcert -file shared-server-resources/src/main/resources/server.cer -alias server -keystore client/src/test/resources/truststore.jks -storepass secret -noprompt
Код:
client:
ssl:
one-way-authentication-enabled: true
two-way-authentication-enabled: false
trust-store: truststore.jks
trust-store-password: secret
4. Аутентификация клиента (двусторонний TLS)
Следующий шаг нашей работы заключается такой настройке сервера, чтобы он требовал бы аутентификации клиентов. Благодаря этим настройкам мы принудим клиентов идентифицировать себя. При таком подходе сервер тоже сможет проверить подлинность клиента, и то, входит ли он в число доверенных сущностей. Включить аутентификацию клиентов можно, воспользовавшись свойством client-auth, сообщив серверу о том, что ему нужно проверять клиентов.
Приведём файл сервера application.yml к такому виду:
Код:
server:
port: 8443
ssl:
enabled: true
key-store: classpath:identity.jks
key-password: secret
key-store-password: secret
client-auth: need
Код:
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
Код:
keytool -v -genkeypair -dname "CN=Suleyman,OU=Altindag,O=Altindag,C=NL" -keystore client/src/test/resources/identity.jks -storepass secret -keypass secret -keyalg RSA -keysize 2048 -alias client -validity 3650 -deststoretype pkcs12 -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth
Код:
keytool -v -exportcert -file client/src/test/resources/client.cer -alias client -keystore client/src/test/resources/identity.jks -storepass secret -rfc
Код:
keytool -v -importcert -file client/src/test/resources/client.cer -alias client -keystore shared-server-resources/src/main/resources/truststore.jks -storepass secret -noprompt
Приведём файл application.yml клиента к такому виду:
Код:
client:
ssl:
one-way-authentication-enabled: false
two-way-authentication-enabled: true
key-store: identity.jks
key-password: secret
key-store-password: secret
trust-store: truststore.jks
trust-store-password: secret
Код:
server:
port: 8443
ssl:
enabled: true
key-store: classpath:identity.jks
key-password: secret
key-store-password: secret
trust-store: classpath:truststore.jks
trust-store-password: secret
client-auth: need
Примите поздравления! Только что вы настроили двусторонний TLS!
5. Установление двустороннего TLS-соединения с использованием доверенного удостоверяющего центра
Есть и другой способ организации двусторонней аутентификации. Он основан на использовании доверенного удостоверяющего центра. У такого подхода есть сильные и слабые стороны.
Сильные стороны:
- Клиентам не нужно добавлять в свои хранилища сертификат сервера.
- Серверу не нужно добавлять в своё хранилище все сертификаты клиентов.
- Меньше времени уходит на поддержку такой конфигурации, так как срок действия может истечь лишь у сертификата удостоверяющего центра.
- Разработчик теряет контроль над тем, каким приложениям разрешено обращаться к его приложению. Разрешение даётся любому приложению, у которого есть подписанный сертификат от удостоверяющего центра.
1. Создание удостоверяющего центра
Обычно работают с уже существующими удостоверяющими центрами, которым, для подписи, нужно передавать сертификаты. Здесь же мы создадим собственный удостоверяющий центр и подпишем с его помощью сертификаты клиента и сервера. Для создания удостоверяющего центра воспользуемся такой командой:
Код:
keytool -v -genkeypair -dname "CN=Root-CA,OU=Certificate Authority,O=Thunderberry,C=NL" -keystore root-ca/identity.jks -storepass secret -keypass secret -keyalg RSA -keysize 2048 -alias root-ca -validity 3650 -deststoretype pkcs12 -ext KeyUsage=digitalSignature,keyCertSign -ext BasicConstraints=ca:true,PathLen:3
2. Создание файла запроса на подпись сертификата
Для того чтобы подписать сертификат — нужен .csr-файл (Certificate Signing Request, файл запроса на подпись сертификата). Создать его можно с помощью особой команды.
Вот её вариант для сервера:
Код:
keytool -v -certreq -file shared-server-resources/src/main/resources/server.csr -keystore shared-server-resources/src/main/resources/identity.jks -alias server -keypass secret -storepass secret -keyalg rsa
Код:
keytool -v -certreq -file client/src/test/resources/client.csr -keystore client/src/test/resources/identity.jks -alias client -keypass secret -storepass secret -keyalg rsa
3. Подписание сертификата с помощью запроса на подпись сертификата
Вот соответствующая команда для клиента:
Код:
keytool -v -gencert -infile client/src/test/resources/client.csr -outfile client/src/test/resources/client-signed.cer -keystore root-ca/identity.jks -storepass secret -alias root-ca -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth
Код:
keytool -v -gencert -infile shared-server-resources/src/main/resources/server.csr -outfile shared-server-resources/src/main/resources/server-signed.cer -keystore root-ca/identity.jks -storepass secret -alias root-ca -ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement -ext ExtendedKeyUsage=serverAuth,clientAuth -ext SubjectAlternativeName:c=DNS:localhost,IP:127.0.0.1
4. Замена неподписанного сертификата подписанным
В хранилище идентификационных данных сервера и клиента всё ещё хранится неподписанный сертификат. Сейчас можно заменить его на подписанный. У инструмента keytool есть одна не вполне понятная особенность. А именно — он не позволяет напрямую импортировать в хранилище подписанный сертификат. Если попытаться это сделать — будет выведено сообщение об ошибке. Сертификат, подписанный удостоверяющим центром, должен быть представлен в файле identity.jks.
Экспортируем подписанный сертификат:
Код:
keytool -v -exportcert -file root-ca/root-ca.pem -alias root-ca -keystore root-ca/identity.jks -storepass secret -rfc
Код:
keytool -v -importcert -file root-ca/root-ca.pem -alias root-ca -keystore client/src/test/resources/identity.jks -storepass secret -noprompt
keytool -v -importcert -file client/src/test/resources/client-signed.cer -alias client -keystore client/src/test/resources/identity.jks -storepass secret
keytool -v -delete -alias root-ca -keystore client/src/test/resources/identity.jks -storepass secret
Код:
keytool -v -importcert -file root-ca/root-ca.pem -alias root-ca -keystore shared-server-resources/src/main/resources/identity.jks -storepass secret -noprompt
keytool -v -importcert -file shared-server-resources/src/main/resources/server-signed.cer -alias server -keystore shared-server-resources/src/main/resources/identity.jks -storepass secret
keytool -v -delete -alias root-ca -keystore shared-server-resources/src/main/resources/identity.jks -storepass secret
5. Организация взаимодействия клиента и сервера, основанного исключительно на доверии к удостоверяющему центру
Теперь нужно настроить клиент и сервер так, чтобы они доверяли бы только удостоверяющему центру. Сделать это можно, импортировав сертификат удостоверяющего центра в хранилища TrustStore клиента и сервера.
Сделаем это, выполнив на клиенте следующую команду:
Код:
keytool -v -importcert -file root-ca/root-ca.pem -alias root-ca -keystore client/src/test/resources/truststore.jks -storepass secret -noprompt
Код:
keytool -v -importcert -file root-ca/root-ca.pem -alias root-ca -keystore shared-server-resources/src/main/resources/truststore.jks -storepass secret -noprompt
Выполним на клиенте такую команду:
Код:
keytool -v -delete -alias server -keystore client/src/test/resources/truststore.jks -storepass secret
Код:
keytool -v -delete -alias client -keystore shared-server-resources/src/main/resources/truststore.jks -storepass secret
6. Автоматизация различных подходов к аутентификации
Всё, о чём мы говорили выше, можно автоматизировать с помощью скриптов, которые находятся в папке script рассматриваемого нами проекта. Для запуска скриптов можете воспользоваться следующими командами:
- ./configure-one-way-authentication — настройка односторонней аутентификации.
- ./configure-two-way-authentication-by-trusting-each-other my-company-name — настройка двусторонней аутентификации.
- ./configure-two-way-authentication-by-trusting-root-ca my-company-name — настройка двусторонней аутентификации с использованием удостоверяющего центра.
Ниже приведён список протестированных клиентов. Настройки для HTTP-клиента, написанного на чистом Java, можно найти в классе ClientConfig. В директории service нашего проекта содержатся отдельные HTTP-клиенты, выполняющие демонстрационные запросы. Настройки HTTP-клиентов, основанных на Kotlin и Scala, включены в состав проекта в виде вложенных классов. Все примеры клиентов используют одну и ту же базовую конфигурацию SSL, созданную в классе SSLConfig.
Java:
- Apache HttpClient → Настройки клиента | Пример запроса
- Apache HttpAsyncClient → Настройки клиента | Пример запроса
- Apache 5 HttpClient → Настройки клиента | Пример запроса
- Apache 5 HttpAsyncClient → Настройки клиента | Пример запроса
- JDK HttpClient → Настройки клиента | Пример запроса
- Old JDK HttpClient → Настройки клиента и пример запроса
- Netty Reactor → Настройки клиента | Пример запроса
- Jetty Reactive HttpClient → Настройки клиента | Пример запроса
- Spring RestTemplate → Настройки клиента | Пример запроса
- Spring WebFlux WebClient Netty → Настройки клиента | Пример запроса
- Spring WebFlux WebClient Jetty → Настройки клиента | Пример запроса
- OkHttp → Настройки клиента | Пример запроса
- Клиент Jersey → Настройки клиента | Пример запроса
- Старый клиент Jersey → Настройки клиента | Пример запроса
- Google HttpClient → Настройки клиента | Пример запроса
- Unirest → Настройки клиента | Пример запроса
- Retrofit → Настройки клиента | Пример запроса
- Асинхронный Http-клиент → Настройки клиента | Пример запроса
- Feign → Настройки клиента | Пример запроса
- Methanol → Настройки клиента | Пример запроса
- Vertx Webclient → Настройки клиента и пример запросаhttps://github.com/Hakky54/mutual-t...dag/client/service/VertxWebClientService.java
Kotlin:
- Fuel → Настройки клиента и пример запроса
- Http4k с Apache 4 → Настройки клиента | Пример запроса
- Http4k с Async Apache 4 → Настройки клиента | Пример запроса
- Http4k с Apache 5 → Настройки клиента | Пример запроса
- Http4k с Async Apache 5 → Настройки клиента | Пример запроса
- Http4k с Java Net → Настройки клиента | Пример запроса
- Http4k с Jetty → Настройки клиента | Пример запроса
- Http4k с OkHttp → Настройки клиента | Пример запроса
- Kohttp → Настройки клиента и пример запроса
- Ktor с движком Android → Настройки клиента | Пример запроса
- Ktor с движком Apache → Настройки клиента | Пример запроса
- Ktor c CIO-движком (I/O на основе корутин) → Настройки клиента | Пример запроса
- Ktor с движком Okhttp → Настройки клиента | Пример запроса
Scala:
- Twitter Finagle → Настройки клиента | Пример запроса
- Twitter Finagle Featherbed → Настройки клиента и пример запроса
- HTTP-клиент Akka → Настройки клиента | Пример запроса
- Dispatch Reboot → Настройки клиента и пример запроса
- ScalaJ / Simplified Http Client → Настройки клиента и пример запроса
- Sttp → Настройки клиента и пример запроса
- Requests-Scala → Настройки клиента и пример запроса
- Клиент Http4s Blaze → Настройки клиента | Пример запроса
- Клиент Http4s Java Net → Настройки клиента | Пример запроса
Автор оригинала: Hakan Altındağ
https://dzone.com/articles/hakky54mutual-tls-1