Configure Spring Boot to redirect HTTP to HTTPS
1. Use both HTTP and HTTPS
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)
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)
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 ...
}
Spring Boot Tutorials
- Install Spring Tool Suite for Eclipse
- Spring Tutorial for Beginners
- Spring Boot Tutorial for Beginners
- Spring Boot Common Properties
- Spring Boot and Thymeleaf Tutorial with Examples
- Spring Boot and FreeMarker Tutorial with Examples
- Spring Boot and Groovy Tutorial with Examples
- Spring Boot and Mustache Tutorial with Examples
- Spring Boot and JSP Tutorial with Examples
- Spring Boot, Apache Tiles, JSP Tutorial with Examples
- Use Logging in Spring Boot
- Application Monitoring with Spring Boot Actuator
- Create a Multi Language web application with Spring Boot
- Use multiple ViewResolvers in Spring Boot
- Use Twitter Bootstrap in Spring Boot
- Spring Boot Interceptors Tutorial with Examples
- Spring Boot, Spring JDBC and Spring Transaction Tutorial with Examples
- Spring JDBC Tutorial with Examples
- Spring Boot, JPA and Spring Transaction Tutorial with Examples
- Spring Boot and Spring Data JPA Tutorial with Examples
- Spring Boot, Hibernate and Spring Transaction Tutorial with Examples
- Integrating Spring Boot, JPA and H2 Database
- Spring Boot and MongoDB Tutorial with Examples
- Use Multiple DataSources with Spring Boot and JPA
- Use Multiple DataSources with Spring Boot and RoutingDataSource
- Create a Login Application with Spring Boot, Spring Security, Spring JDBC
- Create a Login Application with Spring Boot, Spring Security, JPA
- Create a User Registration Application with Spring Boot, Spring Form Validation
- Example of OAuth2 Social Login in Spring Boot
- Run background scheduled tasks in Spring
- CRUD Restful Web Service Example with Spring Boot
- Spring Boot Restful Client with RestTemplate Example
- CRUD Example with Spring Boot, REST and AngularJS
- Secure Spring Boot RESTful Service using Basic Authentication
- Secure Spring Boot RESTful Service using Auth0 JWT
- Spring Boot File Upload Example
- Spring Boot File Download Example
- Spring Boot File Upload with jQuery Ajax Example
- Spring Boot File Upload with AngularJS Example
- Create a Shopping Cart Web Application with Spring Boot, Hibernate
- Spring Email Tutorial with Examples
- Create a simple Chat application with Spring Boot and Websocket
- Deploy Spring Boot Application on Tomcat Server
- Deploy Spring Boot Application on Oracle WebLogic Server
- Install a free Let's Encrypt SSL certificate for Spring Boot
- Configure Spring Boot to redirect HTTP to HTTPS
- Fetch data with Spring Data JPA DTO Projections
Show More