Настройте Spring Boot для перенаправления HTTP на HTTPS
1. Совместное использование HTTP и HTTPS
По умолчанию приложение Spring Boot использует только один из двух протоколов: HTTP или HTTPS. Вопрос в том, как использовать эти два протокола одновременно.
Сначала откройте файл application.properties и добавьте свойство server.http.port, чтобы определить порт для HTTP, и свойство server.port для HTTPS.
Примечание: server.http.port - это свойство, которое вы определяете и недоступно в 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
Затем создайте класс HttpHttpsConfigV1 и настройте Spring Boot на одновременное использование двух протоколов http и https.
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)
Основная цель настройки Spring Boot для поддержки протоколов HTTP и HTTPS состоит в том, чтобы сделать приложение способным принимать входящие запросы (request) через HTTP и автоматически перенаправлять (redirect) их на 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
Теперь давайте создадим вторую версию, класс HttpHttpsConfigV2 заменяет класс HttpHttpsConfigV1, который позволяет вашему приложению Spring Boot использовать как протоколы HTTP, так и HTTPS. Однако все запросы по протоколу HTTP будут автоматически перенаправлены (redirect) на 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)
В некоторых случаях вы хотите, чтобы Spring Boot поддерживал как протоколы HTTP, так и HTTPS и только автоматически перенаправлял с HTTP на HTTPS по указанным путям (path). Это можно сделать с помощью 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
Класс HttpHttpsConfigV3 позволяет Spring Boot использовать HTTP и HTTPS одновременно:
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 - это слой между пользователем и Controller, который может отклонять, изменять или перенаправлять запросы пользователя. Основываясь на этой функции Interceptor, вы можете использовать его для обнаружения HTTP Request и перенаправления их на 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;
}
}
В конечном итоге, вам нужно зарегистрировать класс HttpHttpsInterceptor с помощью Spring Boot и указать, какие пути (path) должны проходить через этот Interceptor. Это означает, что они будут перенаправлены на HTTPS, а другие пути будут использовать оба протокола HTTP и HTTPS.
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
- Установите Spring Tool Suite для Eclipse
- Руководство Spring для начинающих
- Руководство Spring Boot для начинающих
- Общие свойства Spring Boot
- Руководство Spring Boot и Thymeleaf
- Руководство Spring Boot и FreeMarker
- Руководство Spring Boot и Groovy
- Руководство Spring Boot и Mustache
- Руководство Spring Boot и JSP
- Руководство Spring Boot, Apache Tiles, JSP
- Используйте Logging в Spring Boot
- Мониторинг приложений с помощью Spring Boot Actuator
- Создание веб-приложения с несколькими языками с помощью Spring Boot
- Используйте несколько ViewResolver в Spring Boot
- Используйте Twitter Bootstrap в Spring Boot
- Руководство Spring Boot Interceptor
- Руководство Spring Boot, Spring JDBC и Spring Transaction
- Руководство Spring JDBC
- Руководство Spring Boot, JPA и Spring Transaction
- Руководство Spring Boot и Spring Data JPA
- Руководство Spring Boot, Hibernate и Spring Transaction
- Интеграция Spring Boot, JPA и H2 Database
- Руководство Spring Boot и MongoDB
- Используйте несколько DataSources с Spring Boot и JPA
- Используйте несколько DataSource с Spring Boot и RoutingDataSource
- Создайте приложение для входа с Spring Boot, Spring Security, Spring JDBC
- Создайте приложение для входа с Spring Boot, Spring Security, JPA
- Создайте приложение регистрации пользователей с помощью Spring Boot, Spring Form Validation
- Пример OAuth2 Social Login в Spring Boot.
- Запускать фоновые запланированные задачи в Spring
- Пример CRUD Restful Web Service c Spring Boot
- Пример Spring Boot Restful Client c RestTemplate
- Пример CRUD с Spring Boot, REST и AngularJS
- Защита Spring Boot RESTful Service используя Basic Authentication
- Защита Spring Boot RESTful Service используя Auth0 JWT
- Пример Upload file c Spring Boot
- Пример Download file c Spring Boot
- Пример Upload file c Spring Boot и jQuery Ajax
- Пример Upload file c Spring Boot и AngularJS
- Создание веб-приложения для корзины покупок с помощью Spring Boot, Hibernate
- Руководство Spring Email
- Создайте простое приложение Chat с Spring Boot и Websocket
- Разверните приложение Spring Boot на Tomcat Server
- Развертывание приложения Spring Boot на Oracle WebLogic Server
- Установите бесплатный сертификат Let's Encrypt SSL для Spring Boot
- Настройте Spring Boot для перенаправления HTTP на HTTPS
Show More