1 简介
之前讲解的 Springboot 整合 https 用的是 tomcat 作为容器, tomcat 也是一个流行多年的老牌 Java 容器了. 但针对不同的场景, 还是会有不同的选择, 如 Jetty.Jetty 是架构相对简单, 基于 Handler 的灵活可扩展的 Servlet 容器. 更多详情请参考官方文档.
(1)Springboot 整合 https 原来这么简单
(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 端口都可以实现重定向:
3 总结
本文没有太多的原理可讲, 之前的文章已经讲了不少 https 相关的知识了, 有兴趣的同学还是翻看之前的文章吧.
本文详细代码可在南瓜慢说公众号回复 < SpringbootSSLRedirectJetty > 获取.
来源: https://www.cnblogs.com/larrydpk/p/12813908.html