programing

HTTPS/HTTP 포트를 실행하도록 스프링 부트를 설정하는 방법

muds 2023. 4. 1. 10:03
반응형

HTTPS/HTTP 포트를 실행하도록 스프링 부트를 설정하는 방법

스프링 부트에는 웹 포트 및 SSL 설정을 구성하는 속성이 몇 가지 있지만 SSL 증명서가 설정되면 http 포트는 https 포트로 바뀝니다.

그럼 어떻게 하면 양쪽 포트가 동시에 가동되도록 할 수 있을까요?예를 들어 80과 443을 동시에 실행할 수 있을까요?

보시는 바와 같이 1개의 포트에 대한 속성은 1개뿐입니다.이 경우 "server.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도 사용하려고 합니다.도와주시면 감사하겠습니다!

있는 Boot에서 합니다.2.0.0★★★★

@Component
public class HttpServer {
  @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;
  }
}

또는 Kotlin 버전:

@Component
class HttpServer {
  @Bean
  fun servletContainer(@Value("\${server.http.port}") httpPort: Int): ServletWebServerFactory {
    val connector = Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL)
    connector.setPort(httpPort)

    val tomcat = TomcatServletWebServerFactory()
    tomcat.addAdditionalTomcatConnectors(connector)
    return tomcat
  }
}

속성을 사용한 스프링부트 설정.커넥터를 1개만 설정할 수 있습니다.필요한 것은 여러 개의 커넥터입니다.이를 위해서는 Configuration클래스를 작성해야 합니다.의 지시에 따릅니다.

https://docs.spring.io/spring-boot/docs/1.2.3.RELEASE/reference/html/howto-embedded-servlet-containers.html

아래에서는 속성을 통해 HTTPS를 구성한 후 Embedded Servlet Container Customizer를 통해 HTTP를 구성하는 작업 예를 볼 수 있습니다.

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);
            }
        }
    };
}
}

Bellow 는, HTTP/HTTPS 포토를 모두 undertow 로 유효하게 하는 방법의 간단한 예입니다.

Spring Boot에서는 설정에 따라 포트를 1개만 열 수 있습니다.두 번째 포트는 프로그래밍 방식으로 열어야 합니다.

먼저 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 포트 읽기 속성 중 하나를 열 수 있습니다.아래 그림과 같이 적절한 설정을 추가하면 HTTP 포트를 열어도 됩니다.

#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

필요에 따라 HTTP 포트를 연 것과 동일한 방법으로 다른 SSL 포트를 열 수 있습니다.

 .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;
    }
}

다른 Spring Boot 2.x 솔루션:

private static final int HTTP_PORT = 80;
private static final int HTTPS_PORT = 443;
private static final String HTTP = "http";
private static final String USER_CONSTRAINT = "CONFIDENTIAL";

@Bean
public ServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
        @Override
        protected void postProcessContext(Context context) {
            SecurityConstraint securityConstraint = new SecurityConstraint();
            securityConstraint.setUserConstraint(USER_CONSTRAINT);
            SecurityCollection collection = new SecurityCollection();
            collection.addPattern("/*");
            securityConstraint.addCollection(collection);
            context.addConstraint(securityConstraint);
        }
    };
    tomcat.addAdditionalTomcatConnectors(redirectConnector());
    return tomcat;
}

private Connector redirectConnector() {
    Connector connector = new Connector(
            TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
    connector.setScheme(HTTP);
    connector.setPort(HTTP_PORT);
    connector.setSecure(false);
    connector.setRedirectPort(HTTPS_PORT);
    return connector;
}

properties server.port=443으로 설정합니다.

https://github.com/creactiviti/spring-boot-starter-acme 를 참조해 주세요.LetsEncrypt 기반 SSL 인증서를 매우 쉽게 자동 생성할 수 있습니다.

README에서:

  1. 모듈을 pom.xml 파일에 의존관계로 추가합니다.

  2. 프로젝트를 구축합니다.

  3. 대상 시스템에 배포하고 도메인 이름을 해당 시스템의 IP 주소로 지정합니다.LetsEncrypt는 이 모듈에 의해 공개된http://your-domain/.well-known/acme-challenge/{token} 엔드포인트에 콜백을 함으로써 도메인의 소유권을 확인합니다.

  4. 서버의 $PATH에서 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

상위 답변은 모두 훌륭하고 아마 효과가 있을 것입니다만, 저는 Undertow를 JHipster와 함께 사용하고 있기 때문에, 이 답변은 저에게 효과가 없었습니다(그리고 이것이 주된 검색 결과였습니다).Undertow의 올바른 코드는 이 호에서 구체적으로 언급됩니다.

@Bean
public UndertowServletWebServerFactory embeddedServletContainerFactory() {
    UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
    factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
        @Override
        public void customize(Undertow.Builder builder) {
            builder.addHttpListener(8080, "0.0.0.0");
        }
    });
    return factory;
}

언급URL : https://stackoverflow.com/questions/30896234/how-set-up-spring-boot-to-run-https-http-ports

반응형