Springboot以Jetty为容器实现http重定向到https
1 简介
之前讲解的
Springboot
整合
https
用的是
tomcat
作为容器,
tomcat
也是一个流行多年的老牌Java容器了。但针对不同的场景,还是会有不同的选择,如
Jetty
。
Jetty
是架构相对简单、基于
Handler
的灵活可扩展的
Servlet
容器。更多详情请参考
官方文档
。
另外建议阅读其它相关文章:
(2) HTTPS之密钥知识与密钥工具Keytool和Keystore-Explorer
(3) Springboot以Tomcat为容器实现http重定向到https的两种方式
2 重定向实现
为了代码结构清晰一点,把配置拆成两个类。
2.1 重定向
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);
2.2 同时打开http和https
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);
实现的重定向的结果如下:
2.3 更好玩的多http端口
有意思的是,我们可以实现多个http
端口同时启用,并都重定向到https
,增加代码如下即可:
ServerConnector connector2 = new ServerConnector(server);
connector2.addConnectionFactory(new HttpConnectionFactory(httpConfiguration));
connector2.setPort(httpPort + 1);
server.addConnector(connector2);
效果如下,使用80
和81
端口都可以实现重定向:
本文没有太多的原理可讲,之前的文章已经讲了不少https
相关的知识了,有兴趣的同学还是翻看之前的文章吧。