Приложение Spring Java не находит файл хранилища ключей

#java #linux #spring #ssl #tomcat

#java #linux #spring #ssl #tomcat

Вопрос:

Я пытаюсь настроить простое приложение Spring на использование SSL и разместить его в Digital Ocean. Почему мое приложение не находит файл хранилища ключей?

Настроенный мной droplet основан на Ubuntu 18.04. Я использовал Letsencrypt для получения сертификата и это руководство для создания файла PKCS. Я настроил свой файл application.properties для поиска в текущем каталоге jar-файла следующим образом:

 security.require-ssl:true
server.ssl.key-store:keystore.p12
server.ssl.key-store-password:<password>
server.ssl.key-store-type:PKCS12
server.ssl.key-alias:<alias>

  

Я бы ожидал, что это запустится и веб-сервер запустится на настроенном порту. Однако в трассировке стека я получаю следующее:

 Caused by: java.io.FileNotFoundException: /root/software/gimmememe/target/keystore.p12  (No such file or directory)
  

Как ни странно, когда я запускаю тот же jar с тем же файлом keystore.p12 на моем собственном компьютере с Windows, он работает нормально:

 o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 9123 (https) with context path ''
meme.Application                         : Started Application in 4.985 seconds (JVM running for 5.464)
  

Я не думаю, что это проблема с разрешениями на компьютере Ubuntu, поскольку я попытался установить разрешения для файла хранилища ключей следующим образом:

 -rw-r--r-- 1 root root     4274 Mar 26 18:44 keystore.p12
  

Я запускаю свой jar-файл с помощью следующей команды (также пробовал с sudo infront):

 java -jar gimme-meme-1.0.0.war
  

Комментарии:

1. Ваш tomcat запущен от имени root? В целевом каталоге.

2. Я использую встроенный tomcat только в Spring. Я не уверен, что именно так это работает, но я просто запускаю jar из командной строки. Также я не буду запускаться от имени root, когда все это будет настроено.

3. Не существует такого понятия, как «каталог curremt файла JAR». Существует текущий рабочий каталог и каталог, в котором находится файл JAR, и они не обязательно совпадают, особенно в веб-контейнере.

4. Тогда извините за путаницу. Я имею в виду каталог, в котором находится JAR, и именно туда я также помещаю файл keystore.p12

5. Итак, тогда вам нужно назвать его полностью, потому что контейнер ищет не это. Вы указали только имя файла, поэтому оно просматривается в его текущем рабочем каталоге, и вы можете увидеть, что это такое, из сообщения об ошибке. Итак, ошибка, поместите это туда .

Ответ №1:

Spring загружает файл из classpath, что позволяет, поэтому вы должны добавить к пути этот префикс classpath: , например

 server.ssl.key-store : classpath:keystore.p12
  

Или если вы используете = символ в качестве разделителя ключа / значения:

 server.ssl.key-store = classpath:keystore.p12
  

Имейте в виду, что значение обрезается только с левой стороны, поэтому после значения не должно быть никаких конечных пробелов.

Комментарии:

1. Похоже, что на компьютере Ubuntu Spring не очищал завершающий пробел.

Ответ №2:

У меня были точно такие же проблемы, и я смог их решить.
Я сохранил файл хранилища ключей в src /main /resources /keystore.p12, но в файле jar он находился непосредственно в разделе classes / .
Мое решение было:

 server.ssl.key-store=classpath:keystore.p12   
  

Ответ №3:

Похоже, что ваше приложение просто ищет в текущем каталоге файл хранилища ключей.p12, как указано:

Caused by: java.io.FileNotFoundException: /root/software/gimmememe/target/keystore.p12 (No such file or directory)

Скорее всего, вам нужно сообщить Spring Boot, что файл находится в jar.

Например, если вы сохраните файл по адресу src/main/resources , gradle amp; maven поместит этот файл в корень classpath. Чтобы передать эту информацию приложению spring boot, вы захотите сообщить ему, что файл находится в classpath.

Это означает, что вам нужно установить server.ssl.key-store значение classpath:keystore.p12 , чтобы Spring знал, что ему нужно загрузить хранилище ключей из пути к классу архива.

— РЕДАКТИРОВАТЬ —

Вот пример того, у кого возникла похожая проблема, которая иллюстрирует это исправление.

Аналогичная проблема на Github

Комментарии:

1. ‘В текущем каталоге файла JAR’ не означает ‘в файле JAR’.

2. Спасибо за предложение. Я попытался поместить файл keystore.p12 в src/main/resources , и он действительно включен в выходной файл jar. Я также добавил classpath: перед именем файла и получил следующую ошибку: FileNotFoundException: class path resource [keystore.p12 ] cannot be resolved to URL because it does not exist Я считаю, что это должно быть проблемой среды, учитывая, что оно отлично работает на моем компьютере с Windows.

3. @MZokov, если вы попытаетесь запустить ту же java -jar команду со своего компьютера с Windows, с файлом в jar, это сработает? Если мы сможем заставить это работать, то оно должно быть перенесено туда, где вы развертываете приложение. Другой вариант — просто скопировать файл .p12 туда, где вы развертываете приложение, и поместить его рядом с запущенным jar. Я лично предпочитаю объединять его, чтобы jar был переносимым и мог работать где угодно.

4. Кроме того, если вы запускаете проект как war , src/main/resources возможно, на самом деле он не находится в корне classpath — возможно, вам потребуется поместить его в src/main/resources/WEB-INF , я не уверен, нужно ли его дополнительно вложить, но wars обрабатываются иначе, чем чисто spring boot jars.

5. На самом деле я получаю ту же ошибку на своем компьютере с Windows. FileNotFoundException: class path resource [keystore.p12 ] cannot be resolved to URL because it does not exist . Я также попробую обычный jar вместо war. Я не уверен, что мне обязательно нужно, чтобы это была война.