1 introduction

This article will show you how to code Http to Https redirection in Springboot. This article will cover only Tomcat as a container, but others will be covered later.

I recommend reading previous articles:

(1) Springboot integration HTTPS turns out to be so simple

(2) HTTPS key knowledge and key tools Keytool and Keystore-Explorer

2 Related Concepts

2.1 What is Redirection

The so-called redirection is that you originally want to browse address A, but when you arrive at the server, the server thinks that the interface of address A is no longer available or you have no access permission, and does not want you to access address A. I tell you another address B, and then you go to address B.

There are generally two return codes for redirects:

  • 301: Permanent redirection;
  • 302: Temporary redirection.

Check the details of the web through Chrome, and record the redirection of several websites:

Web site The domain name Redirection code Redirected url
Pumpkin let alone www.pkslow.com 301 www.pkslow.com
Google www.google.com 307 www.google.com
Apple www.apple.com 307 www.apple.com
Alipay www.alipay.com 301 www.alipay.com
QQ www.qq.com 302 www.qq.com
baidu www.baidu.com 307 www.baidu.com

Note: 307 is also a redirection, is a new status code.

2.2 Why Redirection

Given my list above, is it possible to get a sense of why this redirection is necessary? It’s not hard to see that all of the above redirects do one thing: redirect HTTP to HTTPS. Here’s why:

(1) HTTP is not secure, should use secure HTTPS url;

(2) But you can’t ask users to type in https:// every time they type a website, which is too cumbersome, so people are used to typing only the domain name, or even WWW. They don’t want to enter. Therefore, the user’s input is actually to access HTTP web pages, which need to be redirected to HTTPS to achieve secure access requirements.

2.3 How do I Enable Redirection

First, the server must support both HTTP and HTTPS, otherwise there would be no redirection at all. Since HTTPS has to be supported, why provide HTTP? Why not just go to HTTPS instead? The reason has been said before, we are used to only enter a simple domain name access, then the arrival is HTTP, if you do not provide HTTP support, users still think your website has been hung.

Both protocols are supported, so you need to open two Socket ports, usually 80 for HTTP and 443 for HTTPS. Then you need to redirect all HTTP requests to HTTPS. Different servers have different implementations, so here’s the implementation of Springboot+Tomcat.

3 Springboot Redirects Tomcat

SpringbootIn order toTomcatAs aServletContainer, there are two ways to implement redirection, one is not usedSpring SecurityThe other is to useSpring Security. The code structure is as follows:

The main class has the following code:

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); }}Copy the code

@ ComponentScan (basePackages = “com. Pkslow. SSL. Controller”) : no wrapped config scanning come in, because want to @ Import to control the use which kinds of means to redirect. There are other ways to control this, such as @conditionalonProperty, which I won’t go into here.

When there is no use Spring Security, using the @ Import (HttpToHttpsContainerFactoryConfig. Class);

When using Spring Security, use the @ Import ({EnableHttpWithHttpsConfig. Class, HttpToHttpsWebSecurityConfig class}).

The configuration file application.properties reads as follows:

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=localhostCopy the code

Two ports need to be specified. Server. port is the HTTPS port. HTTP. Port indicates the HTTP port. Note that in the absence of HTTPS, server.port refers to the HTTP port.

3.1 Configuring the Container Factory For Redirection

Configuration such as HttpToHttpsContainerFactoryConfig, code is as follows:

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; }}Copy the code

CreateHttpConnector () : this method implements the HTTP function and redirects the HTTPS port.

3.2 Configuring Spring Security to Implement Redirection

There are two configuration classes, one for opening the HTTP service and one for implementing redirection.

EnableHttpWithHttpsConfig main effect is on the premise of have HTTPS, to open the HTTP service.

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); }}}Copy the code

HttpToHttpsWebSecurityConfig mainly for Spring Security configuration, it is known to all that Spring Security is very powerful, but also very complex. The key comment has been written in the code:

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 - Implemented using Spring Security http.portMapper().http(httpPort).mapsTo(httpsPort); http.requiresChannel( channel -> channel.anyRequest().requiresSecure() ); Http.authorizerequests ().antmatchers ("/hello").permitall ().anyRequest().authenticated().and(); } @override public void configure(WebSecurity Web) throws Exception { Web.ignoring ().antmatchers ("/actuator").antmatchers ("/actuator/**"); }}Copy the code

4 summarizes

Finally, redirection is implemented, and the result shows:

In this paper, a detailed code in the pumpkin, let alone the public response to < SpringbootSSLRedirectTomcat >.

Reference links:

Spring Security: docs. Spring. IO/Spring – secu…

Springboot 1.4 Redirect: jonaspfeifer. De /redirect-ht…


Visit pumpkin Talk www.pkslow.com for more exciting articles!

Welcome to pay attention to the wechat public number “Pumpkin slow Talk”, will continue to update for you…