Где разместить хранилище ключей для веб-приложения Tomcat с помощью HTTP-клиента Apache
Я пишу процедуру для доступа к удаленному серверу. Этот сервер, к которому я подключаюсь, требует взаимной аутентификации, поэтому я должен предоставить хранилище ключей, и пока я на нем, я бы тоже хотел установить надлежащее хранилище доверенных сертификатов.
Я могу найти множество учебников о том, как создать хранилище ключей с keytool
и множество способов заставить клиента Apache HTTP его распознать, но не то, где его хранить в среде Tomcat, чтобы приложение могло его найти. Каким-то образом поместить его в файл war приложения мне кажется плохой идеей.
Опять же, это не означает, что Tomcat может обрабатывать входящие соединения https - у меня есть команда обратного прокси-сервера, настроенная для этого. Я создаю исходящие соединения https, для которых требуется взаимная аутентификация, т. Е. Как принятие самозаверяющего сертификата конечного сервера, так и предоставление самозаверяющего сертификата клиента моего сервера.
Где вы храните фактические файлы хранилища ключей и доверенных сертификатов в среде Tomcat для использования веб-приложением?
2 ответа
Вы можете поместить свой склад ключей куда угодно, если вы знаете, как сказать httpclient
где загрузить хранилище ключей.
Это, конечно, хитрость.
Использование Apache httpclient для https
Во всем этом беспорядке кода в принятом ответе лежит ключ (ха!) К использованию httpclient
с вашим собственным хранилищем ключей. Жаль, что httpclient
не имеет простого API, такого как "вот путь к моему файлу хранилища ключей, теперь используйте его" или "вот байты для моего хранилища ключей, используйте их" (если вы хотите загрузить хранилище ключей из ClassLoader или чего-то еще), но похоже, это так.
Честно говоря, использование хранилищ ключей и доверенных сертификатов в Java - грязное дело, и обычно это никак не обходится. Я сам написал HTTP-клиент с поддержкой сертификатов клиента, не используя ничего, кроме HttpsURLConnection, а затем добавив к нему компоненты raw-сокетов, и я знаю, насколько это больно.
Код в приведенной выше статье довольно прост, если немного многословен. К сожалению, вам придется сделать его намного более запутанным для кода производственного качества, потому что вы должны выполнять проверку ошибок и т. Д. На каждом этапе процесса, чтобы убедиться, что ваша служба не переключается, когда Вы пытаетесь настроить различные магазины и установить соединение.
Это в основном комментарий к ответу @Christopher Schultz, но, поскольку он включает в себя некоторые фрагменты кода, прошу прощения за то, что я разместил его здесь
К сожалению, httpclient не имеет простого API, такого как "вот путь к моему файлу хранилища ключей, теперь используйте его" или "вот байты для моего хранилища ключей, используйте их" (если вы хотите загрузить хранилище ключей из ClassLoader или что угодно), но, похоже, это так
Вот как можно настроить Apache HttpClient 4.3 для использования определенного хранилища доверия для инициализации контекста SSL.
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(trustStore)
.build();
CloseableHttpClient client = HttpClients.custom()
.setSslcontext(sslContext)
.build();
Можно загрузить материал доверия с такого ресурса
URL resource = getClass().getResource("/com/mycompany/mystuff/my.truststore");
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream inputStream = resource.openStream();
try {
trustStore.load(inputStream, null /*usually not password protected*/);
} finally {
inputStream.close();
}