應用同時支援HTTP和HTTPS

浪天涯&*發表於2024-06-21
生成證書:keytool -genkeypair -keystore test.jks -alias test -keyalg RSA -keysize 2048 -validity 3650
應用配置:
server: port: 18081 #https http-port: 8081 #http ssl: key-store: /test.jks # 金鑰庫路徑 key-store-password: ENC(djVg6Ri/rp7cHwh9ZTmq/Q==) # 金鑰庫密碼 key-alias: test # 金鑰庫別名 enabled: true

閘道器服務(NettyServer):

import cn.hutool.extra.spring.SpringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Objects;

@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(value = "server.ssl.enabled", havingValue = "true")
public class NettyServerCustomer {
    private final HttpHandler httpHandler;

    @PostConstruct
    public void start() {
        Integer httpPort = SpringUtil.getProperty("server.http-port", Integer.class, null);
        if (Objects.nonNull(httpPort)) {
            NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory(httpPort);
            WebServer webServer = factory.getWebServer(httpHandler);
            webServer.start();
            log.info("Netty Server Started, HTTP Port: {}", httpPort);
        }
    }
}

業務服務(Tomcat、Undertow):

import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Slf4j
@Component
@ConditionalOnProperty(value = "server.ssl.enabled", havingValue = "true")
public class TomcatServerCustomer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        Integer httpPort = SpringUtil.getProperty("server.http-port", Integer.class, null);
        if (Objects.nonNull(httpPort)) {
            Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
            connector.setPort(httpPort);
            connector.setScheme("http");
            factory.addAdditionalTomcatConnectors(connector);
            log.info("Tomcat Server Started, HTTP Port: {}", httpPort);
        }
    }
}




import cn.hutool.extra.spring.SpringUtil;
import io.undertow.UndertowOptions;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.SecurityInfo;
import io.undertow.servlet.api.TransportGuaranteeType;
import io.undertow.servlet.api.WebResourceCollection;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Slf4j
@Component
@ConditionalOnProperty(value = "server.ssl.enabled", havingValue = "true")
public class UndertowServerCustomer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
@Override
public void customize(UndertowServletWebServerFactory factory) {
Integer httpPort = SpringUtil.getProperty("server.http-port", Integer.class, null);
Integer httpsPort = SpringUtil.getProperty("server.port", Integer.class, null);
if (Objects.nonNull(httpPort) && Objects.nonNull(httpsPort)) {
factory.addBuilderCustomizers(builder -> {
builder.addHttpListener(httpPort, "0.0.0.0");
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
});
factory.addDeploymentInfoCustomizers(deploymentInfo ->
deploymentInfo.addSecurityConstraint(
new SecurityConstraint()
.addWebResourceCollection(new WebResourceCollection().addUrlPatterns("/*"))
.setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL)
.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT))
.setConfidentialPortManager(e -> httpsPort));
log.info("Undertow Server Started, HTTP Port: {}", httpPort);
}
}
}

此時應用啟動後,支援http與https;

註冊中心註冊的埠時https,若以http為主,則還需修改 FeignClient、RestTemplate配置以支援https;

若要以http為主,則修改註冊中心註冊埠

spring:
  cloud:
    consul:
      discovery:
        port: ${server.http-port:${server.port}}
    nacos:
      discovery:
        port: ${server.http-port:${server.port}}

若不想啟停https時來回修改埠

import cn.hutool.core.util.BooleanUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;

import java.util.Properties;
/**
* 將該類加入spring.factories
* org.springframework.boot.env.EnvironmentPostProcessor=com.leadingtek.arteryf.gateway.config.ServerPortEnvPostProcessor
*
*/

public class ServerPortEnvPostProcessor implements EnvironmentPostProcessor, Ordered {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        String sslPortEnable = environment.getProperty("server.ssl.enabled");
        Integer httpPort = environment.getProperty("server.http-port", Integer.class);
        if (!BooleanUtil.toBoolean(sslPortEnable) && httpPort != null) {
            Properties properties = new Properties();
            properties.put("server.port", httpPort);
            MutablePropertySources propertySources = environment.getPropertySources();
            propertySources.addFirst(new PropertiesPropertySource("server-port-properties", properties));
        }
    }

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }
}

相關文章