Configure Spring Boot to redirect HTTP to HTTPS
1. Use both HTTP and HTTPS
No ADS
By default, Spring Boot application uses either HTTP or HTTPS protocol. The question is how to use these two protocols at the same time.
First, open the application.properties file and add server.http.port property to define a port for HTTP, and server.port property for HTTPS.
Note: server.http.port is a property you define and not available in SpringBoot.
application.properties (*)
# (User-defined Property)
# Port for HTTP and read by Spring Boot via @Value("${server.http.port:80}")
server.http.port=8080
# Port for HTTPS and read by Spring Boot via @Value("${server.port:443}")
server.port=8443
server.ssl.key-store=file:/home/tran/SSL/o7planning.org/o7planning_org.p12
server.ssl.key-store-password=P@ssword
server.ssl.key-alias=o7planning
Next, create a HttpHttpsConfigV1 class and configure Spring Boot to use both http and https protocolsat the same time.
HttpHttpsConfigV1.java
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.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpHttpsConfigV1 {
// (User-defined Property)
@Value("${server.http.port:80}")
private int httpPort;
@Bean
public ServletWebServerFactory servletContainer() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setPort(this.httpPort);
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(connector);
return tomcat;
}
}
2. Redirect HTTP to HTTPS (Way 2)
No ADS
The main purpose of configuring Spring Boot for it to support both HTTP and HTTPS protocols is to entitle the application to receive incoming requests via HTTP and automatically redirect them to HTTPS.
application.properties (*)
# (User-defined Property)
# Port for HTTP and read by Spring Boot via @Value("${server.http.port:80}")
server.http.port=8080
# Port for HTTPS and read by Spring Boot via @Value("${server.port:443}")
server.port=8443
server.ssl.key-store=file:/home/tran/SSL/o7planning.org/o7planning_org.p12
server.ssl.key-store-password=P@ssword
server.ssl.key-alias=o7planning
Now let's create a second version, HttpHttpsConfigV2 class replaces HttpHttpsConfigV1, which allows your Spring Boot application to use both HTTP and HTTPS protocols. However, all requests via HTTP protocol will be automatically redirected to HTTPS:
HttpHttpsConfigV2.java
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpHttpsConfigV2 {
// IMPORTANT!!!
// If this parameter is empty then do not redirect HTTP to HTTPS
//
// Defined in application.properties file
@Value(value = "${server.ssl.key-store:}")
private String sslKeyStore;
// Defined in application.properties file
// (User-defined Property)
@Value(value = "${server.http.port:80}")
private int httpPort;
// Defined in application.properties file
@Value("${server.port:443}")
int httpsPort;
@Bean
public ServletWebServerFactory servletContainer() {
boolean needRedirectToHttps = sslKeyStore != null && !sslKeyStore.isEmpty();
TomcatServletWebServerFactory tomcat = null;
if (!needRedirectToHttps) {
tomcat = new TomcatServletWebServerFactory();
return tomcat;
}
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(redirectConnector());
return tomcat;
}
private Connector redirectConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
connector.setRedirectPort(httpsPort);
return connector;
}
}
3. Redirect HTTP to HTTPS (Way 3)
No ADS
In some cases you want Spring Boot to support both HTTP and HTTPS protocols, and only automatically redirect from HTTP to HTTPS with the specified paths. It is absolutely doable with Interceptor.
application.properties (*)
# (User-defined Property)
# Port for HTTP and read by Spring Boot via @Value("${server.http.port:80}")
server.http.port=8080
# Port for HTTPS and read by Spring Boot via @Value("${server.port:443}")
server.port=8443
server.ssl.key-store=file:/home/tran/SSL/o7planning.org/o7planning_org.p12
server.ssl.key-store-password=P@ssword
server.ssl.key-alias=o7planning
The HttpHttpsConfigV3 class allows Spring Boot application to use both HTTP and HTTPS protocols simultaneously:
HttpHttpsConfigV3.java
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.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// @see HttpHttpsInterceptor
@Configuration
public class HttpHttpsConfigV3 {
@Value("${server.http.port:80}")
private int httpPort;
@Bean
public ServletWebServerFactory servletContainer() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setPort(this.httpPort);
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(connector);
return tomcat;
}
}
Interceptor is a middle layer between the user and the Controller. It can deny, modify, or redirect the user's requests. Based on this feature of Interceptor, you can use it to detect HTTP Request(s) and redirect them to HTTPS.
HttpHttpsInterceptor.java
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
@Component
public class HttpHttpsInterceptor implements HandlerInterceptor {
// Defined in application.properties file
@Value(value = "${server.ssl.key-store:}")
private String sslKeyStore;
// Defined in application.properties file
@Value(value = "${server.http.port:80}")
private int httpPort;
// Defined in application.properties file
@Value("${server.port:443}")
int httpsPort;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// @return http or https
String schema = request.getScheme();
// System.out.println("Schema: " + schema);
if("https".equals(schema)) {
return true;
}
if(sslKeyStore == null || sslKeyStore.isEmpty()) {
return true;
}
String serverName = request.getServerName();
// System.out.println("Server Name: " + serverName);
boolean isIP = this.isIP(serverName);
// System.out.println("isIP: " + isIP);
if (isIP) {
// System.out.println("No Redirect isIP = "+ isIP);
return true;
}
int requestedPort = request.getServerPort();
// System.out.println("requestedPort: " + requestedPort);
if (requestedPort == httpPort) { // This will still allow requests on :8080
// System.out.println("Redirect to https");
String queryString = request.getQueryString();
if (queryString == null || queryString.isEmpty()) {
if (httpsPort == 443) {
response.sendRedirect(
"https://" + request.getServerName() + request.getRequestURI());
} else {
response.sendRedirect(
"https://" + request.getServerName() + ":" + httpsPort + request.getRequestURI());
}
} else {
if (httpsPort == 443) {
response.sendRedirect(
"https://" + request.getServerName() + request.getRequestURI() + "?" + queryString);
} else {
response.sendRedirect(
"https://" + request.getServerName() + ":" + httpsPort + request.getRequestURI() + "?" + queryString);
}
}
return false;
}
return true;
}
private boolean isIP(String remoteHost) {
String s = remoteHost.replaceAll("\\.", "");
// System.out.println("isIP? " + s);
try {
Long.parseLong(s);
} catch (Exception e) {
// e.printStackTrace();
return false;
}
return true;
}
}
Finally, you need to register the HttpHttpsInterceptor class with Spring Boot and specify which paths have to go through this Interceptor. That means they will be redirected to HTTPS, and the other paths will use both HTTP and HTTPS protocols.
WebMvcConfig.java
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
@Transactional
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private HttpHttpsInterceptor httpHttpsInterceptor;
//
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(httpHttpsInterceptor);
registry.addInterceptor(httpHttpsInterceptor)//
.addPathPatterns("/path01", "path02/**");
}
// Other configs ...
}
No ADS
Spring Boot Tutorials
- Deploy Spring Boot Application on Oracle WebLogic Server
- Create a User Registration Application with Spring Boot, Spring Form Validation
- Spring Boot File Upload Example
- Spring Boot and Groovy Tutorial with Examples
- Spring Boot and MongoDB Tutorial with Examples
- Spring Boot, Hibernate and Spring Transaction Tutorial with Examples
- Spring Boot and Spring Data JPA Tutorial with Examples
- Secure Spring Boot RESTful Service using Auth0 JWT
- Spring Email Tutorial with Examples
- Spring Boot, Apache Tiles, JSP Tutorial with Examples
- Create a Login Application with Spring Boot, Spring Security, JPA
- Use Twitter Bootstrap in Spring Boot
- Spring Tutorial for Beginners
- Spring Boot Interceptors Tutorial with Examples
- Create a Login Application with Spring Boot, Spring Security, Spring JDBC
- Spring Boot File Upload with jQuery Ajax Example
- Spring Boot and JSP Tutorial with Examples
- Install Spring Tool Suite for Eclipse
- Spring Boot, JPA and Spring Transaction Tutorial with Examples
- Spring Boot and Thymeleaf Tutorial with Examples
- Integrating Spring Boot, JPA and H2 Database
- Spring Boot File Upload with AngularJS Example
- Fetch data with Spring Data JPA DTO Projections
- Use Multiple DataSources with Spring Boot and JPA
- CRUD Example with Spring Boot, REST and AngularJS
- Spring Boot and Mustache Tutorial with Examples
- Spring JDBC Tutorial with Examples
- Install a free Let's Encrypt SSL certificate for Spring Boot
- Spring Boot Tutorial for Beginners
- Spring Boot Common Properties
- Spring Boot, Spring JDBC and Spring Transaction Tutorial with Examples
- Use multiple ViewResolvers in Spring Boot
- Deploy Spring Boot Application on Tomcat Server
- Configure Spring Boot to redirect HTTP to HTTPS
- Example of OAuth2 Social Login in Spring Boot
- Create a simple Chat application with Spring Boot and Websocket
- Use Multiple DataSources with Spring Boot and RoutingDataSource
- Spring Boot and FreeMarker Tutorial with Examples
- Create a Shopping Cart Web Application with Spring Boot, Hibernate
- Spring Boot Restful Client with RestTemplate Example
- Secure Spring Boot RESTful Service using Basic Authentication
- Spring Boot File Download Example
- CRUD Restful Web Service Example with Spring Boot
- Create a Multi Language web application with Spring Boot
- Use Logging in Spring Boot
- Run background scheduled tasks in Spring
- Application Monitoring with Spring Boot Actuator
Show More