内容简介:本文将介绍在建议阅读之前的相关文章:
1 简介
本文将介绍在 Springboot 中如何通过代码实现 Http 到 Https 的重定向,本文仅讲解 Tomcat 作为容器的情况,其它容器将在以后一一道来。
建议阅读之前的相关文章:
(2) HTTPS之密钥知识与密钥工具Keytool和Keystore-Explorer
2 相关概念
2.1 什么叫重定向
所谓重定向,就是本来你想浏览地址A的,但是到达服务端后,服务端认为地址A的界面不在了或者你没权限访问等原因,不想你访问地址A;就告诉你另一个地址B,然后你再去访问地址B。
对于重定向一般有两个返回码:
- 301:永久性重定向;
- 302:暂时性重定向。
通过 Chrome 查看网络详情,记录了几个网站的重定向情况:
| 网站 | 域名 | 重定向代码 | 重定向后的网址 |
|---|---|---|---|
| 南瓜慢说 | www.pkslow.com | 301 | https://www.pkslow.com |
| www.google.com | 307 | https://www.google.com | |
| Apple | www.apple.com | 307 | https://www.apple.com |
| 支付宝 | www.alipay.com | 301 | https://www.alipay.com |
| www.qq.com | 302 | https://www.qq.com | |
| 百度 | www.baidu.com | 307 | https://www.baidu.com |
注:307也是重定向的一种,是新的状态码。
2.2 为什么要重定向
结合我上面特意列的表格,是不是大概想到了为何要做这种重定向?不难发现上面的重定向都在做一件事,就是把 http 重定向为 https 。原因如下:
(1) http 是不安全的,应该使用安全的 https 网址;
(2)但不能要求用户每次输入网站都输入 https:// 吧,这也太麻烦了,所以大家都是习惯于只输入域名,甚至连 www. 都不愿意输入。因此,用户的输入其实都是访问 http 的网页,就需要重定向到 https 以达到安全访问的要求。
2.3 如何做到重定向
首先,服务器必须要同时支持 http 和 https ,不然也就没有重定向一说了。因为 https 是必须提供支持的,那为何还要提供 http 的服务呢?直接访问 https 不就行了,不是多此一举吗?原因之前已经讲过了,大家是习惯于只输入简单域名访问的,这时到达的就是 http ,如果不提供 http 的支持,用户还以为你的网站已经挂了呢。
两种协议都提供支持,所以是需要打开两个 Socket 端口的,一般 http 为 80 ,而 https 为 443 。然后就需要把所有访问 http 的请求,重定向到 https 即可。不同的服务器有不同的实现,现在介绍 Springboot+Tomcat 的实现。
3 Springboot Tomcat实现重定向
Springboot 以 Tomcat 作为 Servlet 容器时,有两种方式可以实现重定向,一种是没有使用 Spring Security 的,另一种是使用了 Spring Security 的。代码结构如下:
主类的代码如下:
package com.pkslow.ssl;
import com.pkslow.ssl.config.containerfactory.HttpToHttpsContainerFactoryConfig;
import com.pkslow.ssl.config.security.EnableHttpWithHttpsConfig;
import com.pkslow.ssl.config.security.HttpToHttpsWebSecurityConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import({EnableHttpWithHttpsConfig.class, HttpToHttpsWebSecurityConfig.class})
//@Import(HttpToHttpsContainerFactoryConfig.class)
@ComponentScan(basePackages = "com.pkslow.ssl.controller")
public class SpringbootSslApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootSslApplication.class, args);
}
}
@ComponentScan(basePackages = "com.pkslow.ssl.controller") :没有把 config 包扫描进来,是因为想通过 @Import 来控制使用哪种方式来进行重定向。当然还可以使用其它方式来控制,如 @ConditionalOnProperty ,这里就不展开讲了。
当没有使用 Spring Security 时,使用 @Import(HttpToHttpsContainerFactoryConfig.class) ;
当使用 Spring Security 时,使用 @Import({EnableHttpWithHttpsConfig.class, HttpToHttpsWebSecurityConfig.class}) 。
配置文件application.properties内容如下:
server.port=443 http.port=80 server.ssl.enabled=true server.ssl.key-store-type=jks server.ssl.key-store=classpath:localhost.jks server.ssl.key-store-password=changeit server.ssl.key-alias=localhost
需要指定两个端口, server.port 为 https 端口; http.port 为 http 端口。注意在没有 https 的情况下, server.port 指的是 http 端口。
3.1 配置Container Factory实现重定向
配置的类为 HttpToHttpsContainerFactoryConfig ,代码如下:
package com.pkslow.ssl.config.containerfactory;
import org.apache.catalina.Context;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpToHttpsContainerFactoryConfig {
@Value("${server.port}")
private int httpsPort;
@Value("${http.port}")
private int httpPort;
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat =
new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(createHttpConnector());
return tomcat;
}
private Connector createHttpConnector() {
Connector connector =
new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setSecure(false);
connector.setPort(httpPort);
connector.setRedirectPort(httpsPort);
return connector;
}
}
createHttpConnector() :这个方法主要是实现了在有 https 前提下,打开 http 的功能,并配置重定向的 https 的端口。
3.2 配置Spring security实现重定向
有两个配置类,一个为打开 http 服务,一个为实现重定向。
EnableHttpWithHttpsConfig 主要作用是在已经有 https 的前提下,还要打开 http 服务。
package com.pkslow.ssl.config.security;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
public class EnableHttpWithHttpsConfig {
@Value("${http.port}")
private int httpPort;
@Component
public class CustomContainer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setPort(httpPort);
connector.setScheme("http");
connector.setSecure(false);
factory.addAdditionalTomcatConnectors(connector);
}
}
}
HttpToHttpsWebSecurityConfig 主要是针对 Spring Security 的配置,众所周知, Spring Security 是功能十分强大,但又很复杂的。代码中已经写了关键的注释:
package com.pkslow.ssl.config.security;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class HttpToHttpsWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${server.port}")
private int httpsPort;
@Value("${http.port}")
private int httpPort;
@Override
protected void configure(HttpSecurity http) throws Exception {
//redirect to https - 用spring security实现
http.portMapper().http(httpPort).mapsTo(httpsPort);
http.requiresChannel(
channel -> channel.anyRequest().requiresSecure()
);
//访问路径/hello不用登陆获得权限
http.authorizeRequests()
.antMatchers("/hello").permitAll()
.anyRequest().authenticated().and();
}
@Override
public void configure(WebSecurity web) throws Exception {
//过滤了actuator后,不会重定向,也不用权限校验,这个功能非常有用
web.ignoring()
.antMatchers("/actuator")
.antMatchers("/actuator/**");
}
}
4 总结
最后实现了重定向,结果展示:
本文详细代码可在 南瓜慢说 公众号回复< SpringbootSSLRedirectTomcat >获取。
参考链接:
Spring Security: https://docs.spring.io/spring...
Springboot 1.4重定向: https://jonaspfeifer.de/redir...
欢迎访问 南瓜慢说 www.pkslow.com 获取更多精彩文章!
欢迎关注微信公众号< 南瓜慢说 >,将持续为你更新...
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Caching
Duane Wessels / O'Reilly Media, Inc. / 2001-6 / 39.95美元
On the World Wide Web, speed and efficiency are vital. Users have little patience for slow web pages, while network administrators want to make the most of their available bandwidth. A properly design......一起来看看 《Web Caching》 这本书的介绍吧!