之前讲解的 Springboot
整合 https
用的是 tomcat
作为容器, tomcat
也是一个流行多年的老牌Java容器了。但针对不同的场景,还是会有不同的选择,如 Jetty
。 Jetty
是架构相对简单、基于 Handler
的灵活可扩展的 Servlet
容器。更多详情请参考 官方文档
。
另外建议阅读其它相关文章:
(1) Springboot整合https原来这么简单
(2) HTTPS之密钥知识与密钥工具Keytool和Keystore-Explorer
(3) Springboot以Tomcat为容器实现http重定向到https的两种方式
为了代码结构清晰一点,把配置拆成两个类。
HttpToHttpsJettyConfig
是与 Jetty
强相关的配置类,继承于 AbstractConfiguration
,以便后续用于 WebServerFactory
的设置,如果没有这个类的配置,那就会同时具有 http
和 https
服务,无法重定向。这个类的配置要求连接必须是安全的。具体代码如下:
package com.pkslow.ssl.config; import org.eclipse.jetty.security.ConstraintMapping; import org.eclipse.jetty.security.ConstraintSecurityHandler; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.WebAppContext; public class HttpToHttpsJettyConfig extends AbstractConfiguration { @Override public void configure(WebAppContext context) throws Exception { Constraint constraint = new Constraint(); constraint.setDataConstraint(Constraint.DC_CONFIDENTIAL); ConstraintMapping mapping = new ConstraintMapping(); mapping.setPathSpec("/*"); mapping.setConstraint(constraint); ConstraintSecurityHandler handler = new ConstraintSecurityHandler(); handler.addConstraintMapping(mapping); context.setSecurityHandler(handler); } }
WebServerFactoryCustomizerConfig
的功能主要是在有 https
的前提下,还要提供 http
,具体代码如下:
package com.pkslow.ssl.config; import org.eclipse.jetty.server.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Configuration; import java.util.Collections; @Configuration public class WebServerFactoryCustomizerConfig implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory> { @Value("${server.port}") private int httpsPort; @Value("${http.port}") private int httpPort; @Override public void customize(ConfigurableJettyWebServerFactory factory) { ((JettyServletWebServerFactory)factory).setConfigurations( Collections.singleton(new HttpToHttpsJettyConfig()) ); factory.addServerCustomizers( server -> { HttpConfiguration httpConfiguration = new HttpConfiguration(); httpConfiguration.setSecurePort(httpsPort); httpConfiguration.setSecureScheme("https"); ServerConnector connector = new ServerConnector(server); connector.addConnectionFactory(new HttpConnectionFactory(httpConfiguration)); connector.setPort(httpPort); server.addConnector(connector); } ); } }
实现的重定向的结果如下:
有意思的是,我们可以实现多个 http
端口同时启用,并都重定向到 https
,增加代码如下即可:
ServerConnector connector2 = new ServerConnector(server); connector2.addConnectionFactory(new HttpConnectionFactory(httpConfiguration)); connector2.setPort(httpPort + 1); server.addConnector(connector2);
效果如下,使用 80
和 81
端口都可以实现重定向:
本文没有太多的原理可讲,之前的文章已经讲了不少 https
相关的知识了,有兴趣的同学还是翻看之前的文章吧。
本文详细代码可在 南瓜慢说 公众号回复< SpringbootSSLRedirectJetty >获取。
欢迎访问 南瓜慢说 www.pkslow.com 获取更多精彩文章!
欢迎关注微信公众号< 南瓜慢说 >,将持续为你更新...