生成證書: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; } }