Как я могу указать свой файл.keystore с помощью Spring Boot и Tomcat?
Я пытаюсь настроить Spring Security для работы со встроенным экземпляром Spring Boot Tomcat. Существует довольно много базовых примеров, которые делают это, но я застрял там, где они заканчиваются - они выполняют базовую аутентификацию через HTTP (не HTTPS).
Я мог бы, вероятно, заставить его работать, если бы у меня был доступ к файлам конфигурации Tomcat (server.xml
) но поскольку Spring Boot использует встроенный экземпляр Tomcat (что в противном случае является очень удобным), у меня нет доступа к файлам конфигурации Tomcat (по крайней мере, насколько мне известно).
Там может быть application.properties
настройка для этого, но я не смог отследить его. Я видел ссылки на server.contextPath
поле в application.properties
я подозреваю, что это может быть связано с заменой файлов конфигурации Tomcat. Даже если это связано, я не знаю, с чего начать - все инструкции Tomcat SSL, которые я видел, начинаются с редактирования существующего server.xml
файл, а не создание с нуля.
Можно ли это сделать с помощью Spring Boot (либо указав фрагмент кода server.xml
или другими способами)? Если нет, то какой самый простой способ сделать это? Я понимаю, что мне может потребоваться исключить компонент Tomcat в Spring Boot, но я бы предпочел избежать этого, если это возможно.
5 ответов
Оказывается, есть способ сделать это, хотя я не уверен, что нашел "правильный" способ, так как для этого требовались часы чтения исходного кода из нескольких проектов. Другими словами, это может быть много глупой работы (но это работает).
Во-первых, нет никакого способа получить доступ к server.xml во встроенном Tomcat, чтобы увеличить или заменить его. Это должно быть сделано программно.
Во-вторых, настройка 'require_https' не помогает, так как вы не можете установить информацию сертификата таким образом. Он настраивает переадресацию с http на https, но не дает вам способа заставить https работать, поэтому пересылка бесполезна. Тем не менее, используйте его с приведенным ниже материалом, который заставляет https работать.
Для начала вам необходимо предоставить EmbeddedServletContainerFactory
как объясняется в документации по поддержке встроенного контейнера сервлетов. Документы для Java, но Groovy будет выглядеть примерно так же. Обратите внимание, что я не смог заставить его распознать @Value
аннотация используется в их примере, но это не нужно. Для groovy просто поместите это в новый файл.groovy и включите этот файл в командную строку при запуске spring
загрузки.
Теперь инструкции говорят, что вы можете настроить TomcatEmbeddedServletContainerFactory
класс, который вы создали в этом коде, чтобы вы могли изменить поведение web.xml, и это правда, но для наших целей важно знать, что вы также можете использовать его для адаптации server.xml
поведение. Действительно, читая исходный код класса и сравнивая его с документами Embedded Tomcat, вы видите, что это единственное место, где это можно сделать. Интересная функция TomcatEmbeddedServletContainerFactory.addConnectorCustomizers()
, который может не сильно походить на Javadocs, но на самом деле дает вам встроенный объект Tomcat для индивидуальной настройки. Просто пройдите вашу собственную реализацию TomcatConnectorCustomizer
и установить то, что вы хотите на данный Connector
в void customize(Connector con)
функция. Теперь есть около миллиарда вещей, которые вы можете сделать с Connector
и я не мог найти полезные документы для этого, но createConnector()
Работайте в этом личном проекте Spring -edded-Tomcat, это очень практическое руководство. Моя реализация в итоге выглядела так:
package com.deepdownstudios.server
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.*
import org.springframework.stereotype.*
@Configuration
class MyConfiguration {
@Bean
public EmbeddedServletContainerFactory servletContainer() {
final int port = 8443;
final String keystoreFile = "/path/to/keystore"
final String keystorePass = "keystore-password"
final String keystoreType = "pkcs12"
final String keystoreProvider = "SunJSSE"
final String keystoreAlias = "tomcat"
TomcatEmbeddedServletContainerFactory factory =
new TomcatEmbeddedServletContainerFactory(this.port);
factory.addConnectorCustomizers( new TomcatConnectorCustomizer() {
void customize(Connector con) {
Http11NioProtocol proto = (Http11NioProtocol) con.getProtocolHandler();
proto.setSSLEnabled(true);
con.setScheme("https");
con.setSecure(true);
proto.setKeystoreFile(keystoreFile);
proto.setKeystorePass(keystorePass);
proto.setKeystoreType(keystoreType);
proto.setProperty("keystoreProvider", keystoreProvider);
proto.setKeyAlias(keystoreAlias);
}
});
return factory;
}
}
Autowiring подхватит эту реализацию и запустит ее. Как только я исправил свой поврежденный файл хранилища ключей (обязательно вызовите keytool с помощью -storetype pkcs12
не -storepass pkcs12
как сообщалось в другом месте), это сработало. Кроме того, было бы гораздо лучше предоставить параметры (порт, пароль и т. Д.) В качестве параметров конфигурации для тестирования и т. Д. Я уверен, что это возможно, если вы можете использовать аннотацию @Value для работы с Groovy.
Начиная с Spring Boot 1.2, вы можете настроить SSL с помощью application.properties
или же application.yml
, Вот пример для application.properties
:
server.port = 8443
server.ssl.key-store = classpath:keystore.jks
server.ssl.key-store-password = secret
server.ssl.key-password = another-secret
То же самое с application.yml
:
server:
port: 8443
ssl:
key-store: classpath:keystore.jks
key-store-password: secret
key-password: another-secret
Вот ссылка на текущую справочную документацию.
Для внешних хранилищ ключей используйте префикс "file:"
server.ssl.key-store=file:config/keystore
Если вы не хотите реализовывать свои connector customizer
вы можете собрать и импортировать библиотеку ( https://github.com/ycavatars/spring-boot-https-kit), которая предоставляет предопределенные connector customizer
, Согласно README, вам нужно только создать хранилище ключей, настроить connector.https.*
, импортировать библиотеку и добавить @ComponentScan("org.ycavatars.sboot.kit")
, Тогда у вас будет соединение HTTPS.
А вот пример настройки, реализованной в Groovy: