Как настроить Spring Boot для запуска портов HTTPS / HTTP



Spring boot имеет некоторые свойства для настройки веб-порта и параметров SSL, но как только сертификат SSL установлен, порт http превращается в порт https.

Итак, как я могу поддерживать работу обоих портов на нем, например: 80 и 443 одновременно?

Как видите, там только свойства для одного порта,в данном случае " сервер.ssl " включен, что автоматически отключает http-порт.

##############
### Server ###
##############
server.port=9043
server.session-timeout=1800
server.ssl.key-store=file:///C:/Temp/config/localhost.jks
server.ssl.key-store-password=localhost
server.ssl.key-password=localhost
server.ssl.trust-store=file:///C:/Temp/config/localhost.jks
server.ssl.trust-store-password=localhost

Я пытаюсь использовать даже Tomcat или Undertow. Я был бы признателен за любую помощь!

42   4  

4 ответов:

Конфигурация Spring Boot с помощью свойств позволяет настроить только один разъем. Что вам нужно, так это несколько соединителей, и для этого вы должны написать класс конфигурации. Следуйте инструкциям в

Https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html

Вы можете найти рабочий пример настройки https через свойства, а затем http, хотя EmbeddedServletContainerCustomizer ниже

Http://izeye.blogspot.com/2015/01/configure-http-and-https-in-spring-boot.html?showComment=1461632100718#c4988529876932015554

server:
  port:
    8080
  ssl:
    enabled:
      true
    keyStoreType:
      PKCS12
    key-store:
      /path/to/keystore.p12
    key-store-password:
      password
  http:
    port:
      8079

@Configuration
public class TomcatConfig {

@Value("${server.http.port}")
private int httpPort;

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            if (container instanceof TomcatEmbeddedServletContainerFactory) {
                TomcatEmbeddedServletContainerFactory containerFactory =
                        (TomcatEmbeddedServletContainerFactory) container;

                Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
                connector.setPort(httpPort);
                containerFactory.addAdditionalTomcatConnectors(connector);
            }
        }
    };
}
}

Принятый в настоящее время ответ работает отлично, но нуждается в некоторой адаптации, если вы хотите, чтобы он работал с Spring Boot 2.0.0 и далее:

@Bean
public ServletWebServerFactory servletContainer(@Value("${server.http.port}") int httpPort) {
    Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
    connector.setPort(httpPort);

    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    tomcat.addAdditionalTomcatConnectors(connector);
    return tomcat;
}

Взгляните на: https://github.com/creactiviti/spring-boot-starter-acme . это позволяет очень легко автоматически генерировать SSL-сертификат на основе LetsEncrypt.

Из README:

  1. Добавьте модуль в ваш pom.xml-файл как зависимость.

  2. Создайте свой проект.

  3. Разверните его на целевой машине и укажите доменное имя на IP-адрес этой машины. LetsEncrypt проверяет ваше право собственности на домен, сделав обратный вызов the http://your-domain/.хорошо известная конечная точка / acme-challenge / {token}, представленная этим модулем.

  4. Убедитесь, что на вашем сервере имеется openssl, доступный по пути$.

  5. Чтобы активировать spring-boot-starter-acme и сгенерировать сертификат выполните:

    sudo java -Dserver.port=80 -Dacme.enabled=true -Dacme.domain-name=<YOUR_DOMAIN_NAME> -Dacme.accept-terms-of-service=true -jar mysecureapp-0.0.1-SNAPSHOT.jar

  6. Проверьте консоль на наличие подтверждения того, что сертификат был успешно сгенерирован.

  7. Остановите приложение и настройте его для использования сгенерированного сертификат:

    server.port=443 server.ssl.key-store=keystore.p12 server.ssl.key-store-password=password server.ssl.keyStoreType=PKCS12

Ниже приведен простой пример того, как включить оба порта HTTP/HTTPS для undertow.

Spring Boot позволяет открыть только один порт по конфигурации. Второй порт должен быть открыт программно.

Откройте порт HTTP сначала программно.

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;

@Configuration
public class UndertowConfig {

@Value("${server.http.port}")
private int httpPort;

@Value("${server.http.interface}")
private String httpInterface;

@Bean
public WebServerFactoryCustomizer<UndertowServletWebServerFactory> containerCustomizer() {
    return (WebServerFactoryCustomizer) factory -> {
        UndertowServletWebServerFactory undertowFactory = (UndertowServletWebServerFactory) factory;
        undertowFactory.getBuilderCustomizers().add(builder -> {
            builder.addHttpListener(httpPort, httpInterface);
        });
    };
}

}

HTTPS по конфигурации

Spring может открыть один из портов HTTP или HTTPS, считывая свойства из доступного источника свойств. Если вы добавите соответствующую конфигурацию, как показано ниже, этого будет достаточно, чтобы откройте порт HTTPs.

#default secured port (Spring will open it automatically)
server.port=8443
#additional HTTP port (will open it in UndertowConfig)
server.http.port=8080
#Open to the world
server.http.interface=0.0.0.0
#These settings tell Spring to open SSL port
server.ssl.keystore=file:${APP_BASE}/conf/server/ssl_selfsigned/server.keystore
server.ssl.key-store-password=xyz
server.ssl.key-password=xyz

HTTPS с помощью ручной настройки

Вы можете открыть другой порт SSL так же, как вы открыли порт HTTP, если хотите, сделав это

 .addHttpsListener(ssl_port, httpInterface, getSSLContext());

Вот как вы можете создать контекст SSL

import javax.net.ssl.*;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;

public SSLContext getSSLContext() throws Exception
{
    return createSSLContext(loadKeyStore(serverKeystore,keyStorePassword),
            loadKeyStore(serverTruststore,trustStorePassword));

}


private SSLContext createSSLContext(final KeyStore keyStore,
                                    final KeyStore trustStore) throws Exception {

    KeyManager[] keyManagers;
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
    keyManagers = keyManagerFactory.getKeyManagers();

    TrustManager[] trustManagers;
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(trustStore);
    trustManagers = trustManagerFactory.getTrustManagers();

    SSLContext sslContext;
    sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keyManagers, trustManagers, null);

    return sslContext;
}


private static KeyStore loadKeyStore(final String storeLoc, final String storePw) throws Exception {
    InputStream stream = Files.newInputStream(Paths.get(storeLoc));
    if(stream == null) {
        throw new IllegalArgumentException("Could not load keystore");
    }
    try(InputStream is = stream) {
        KeyStore loadedKeystore = KeyStore.getInstance("JKS");
        loadedKeystore.load(is, storePw.toCharArray());
        return loadedKeystore;
    }
}
    Ничего не найдено.

Добавить ответ:
Отменить.