Java Spring Boot 将 HTTP 重定向到 HTTPS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26655875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot redirect HTTP to HTTPS
提问by Arseniy Ulakaiev
For Spring Boot based application I have configurared ssl properties at application.properties, see my configuration here:
对于基于 Spring Boot 的应用程序,我在 application.properties 配置了 ssl 属性,请在此处查看我的配置:
server.port=8443
server.ssl.key-alias=tomcat
server.ssl.key-password=123456
server.ssl.key-store=classpath:key.p12
server.ssl.key-store-provider=SunJSSE
server.ssl.key-store-type=pkcs12
And I have added conection at Application.class, like
我在 Application.class 上添加了连接,比如
@Bean
public EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
final TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addAdditionalTomcatConnectors(this.createConnection());
return factory;
}
private Connector createConnection() {
final String protocol = "org.apache.coyote.http11.Http11NioProtocol";
final Connector connector = new Connector(protocol);
connector.setScheme("http");
connector.setPort(9090);
connector.setRedirectPort(8443);
return connector;
}
But when I try the following by
但是当我尝试以下操作时
http://127.0.0.1:9090/
redirect to
重定向到
https://127.0.0.1:8443/
is not performed. Who faced a similar problem?
不执行。谁遇到过类似的问题?
采纳答案by Andy Wilkinson
For Tomcat to perform a redirect, you need to configure it with one or more security constraints. You can do this by post-processing the Context
using a TomcatEmbeddedServletContainerFactory
subclass.
要让 Tomcat 执行重定向,您需要为其配置一个或多个安全约束。您可以通过Context
使用TomcatEmbeddedServletContainerFactory
子类对进行后处理来做到这一点。
For example:
例如:
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@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);
}
};
Due to CONFIDENTIAL
and /*
, this will cause Tomcat to redirect every request to HTTPS. You can configure multiple patterns and multiple constraints if you need more control over what is and is not redirected.
由于CONFIDENTIAL
和/*
,这将导致 Tomcat 将每个请求重定向到 HTTPS。如果您需要更多地控制重定向和未重定向的内容,您可以配置多个模式和多个约束。
回答by jebeaudet
For Jetty (tested with 9.2.14), you need to add an extra configuration to the WebAppContext
(adjust the pathSpec
to your taste) :
对于 Jetty(用 9.2.14 测试),您需要添加额外的配置WebAppContext
(pathSpec
根据您的喜好调整):
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
class HttpToHttpsJettyConfiguration extends AbstractConfiguration
{
// http://wiki.eclipse.org/Jetty/Howto/Configure_SSL#Redirecting_http_requests_to_https
@Override
public void configure(WebAppContext context) throws Exception
{
Constraint constraint = new Constraint();
constraint.setDataConstraint(2);
ConstraintMapping constraintMapping = new ConstraintMapping();
constraintMapping.setPathSpec("/*");
constraintMapping.setConstraint(constraint);
ConstraintSecurityHandler constraintSecurityHandler = new ConstraintSecurityHandler();
constraintSecurityHandler.addConstraintMapping(constraintMapping);
context.setSecurityHandler(constraintSecurityHandler);
}
}
Then wire this class by adding an @Configuration
class implementing EmbeddedServletContainerCustomizer
along with a new Connector
that listen to the non secure port :
然后通过添加一个@Configuration
实现类EmbeddedServletContainerCustomizer
和一个新的Connector
监听非安全端口的类来连接这个类:
@Configuration
public class HttpToHttpsJettyCustomizer implements EmbeddedServletContainerCustomizer
{
@Override
public void customize(ConfigurableEmbeddedServletContainer container)
{
JettyEmbeddedServletContainerFactory containerFactory = (JettyEmbeddedServletContainerFactory) container;
//Add a plain HTTP connector and a WebAppContext config to force redirect from http->https
containerFactory.addConfigurations(new HttpToHttpsJettyConfiguration());
containerFactory.addServerCustomizers(server -> {
HttpConfiguration http = new HttpConfiguration();
http.setSecurePort(443);
http.setSecureScheme("https");
ServerConnector connector = new ServerConnector(server);
connector.addConnectionFactory(new HttpConnectionFactory(http));
connector.setPort(80);
server.addConnector(connector);
});
}
}
This implies that the SSL Connector
is already configured and listening on port 443 in this example.
这意味着 SSLConnector
已在此示例中配置并侦听端口 443。
回答by Rodrigo Quesada
Setting this property on your application*.properties file (and the corresponding servlet-specific configuration for HTTPS headers in case you are running behind a proxy) and having Spring Security set-up (e.g. having org.springframework.boot:spring-boot-starter-securityon your classpath) should be enough:
在您的 application*.properties 文件上设置此属性(以及 HTTPS 标头的相应 servlet 特定配置,以防您在代理后面运行)并设置 Spring Security(例如,具有org.springframework.boot:spring-boot-类路径上的starter-security)应该足够了:
security.require-ssl=true
Now, for some reason that configuration is not honored when basic authentication is disabled (at least on old versions of Spring Boot). So in that case you would need to take an extra step and honor it yourself by manually configuring the security on your code, like this:
现在,出于某种原因,当禁用基本身份验证(至少在旧版本的 Spring Boot 上)时,配置将不被遵守。因此,在这种情况下,您需要采取额外的步骤并通过手动配置代码的安全性来实现它,如下所示:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Inject private SecurityProperties securityProperties;
@Override
protected void configure(HttpSecurity http) throws Exception {
if (securityProperties.isRequireSsl()) http.requiresChannel().anyRequest().requiresSecure();
}
}
So, in case you are using Tomcat behind a proxy, you would have all these properties on your application*.properties file:
因此,如果您在代理后面使用 Tomcat,您的 application*.properties 文件中将拥有所有这些属性:
security.require-ssl=true
server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
回答by Alex Burdusel
The approved answer was not enough for me.
批准的答案对我来说还不够。
I had to also add the following to my web security config, as I am not using the default 8080 port:
我还必须将以下内容添加到我的网络安全配置中,因为我没有使用默认的 8080 端口:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private Environment environment;
@Override
public void configure(HttpSecurity http) throws Exception {
// other security configuration missing
http.portMapper()
.http(Integer.parseInt(environment.getProperty("server.http.port"))) // http port defined in yml config file
.mapsTo(Integer.parseInt(environment.getProperty("server.port"))); // https port defined in yml config file
// we only need https on /auth
http.requiresChannel()
.antMatchers("/auth/**").requiresSecure()
.anyRequest().requiresInsecure();
}
}
回答by rogue lad
Follow only 2 steps.
只需执行 2 个步骤。
1- Add spring security dependency in pom.xml
1- 在 pom.xml 中添加 spring 安全依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2- Add this class on root package of your application.
2- 在应用程序的根包上添加此类。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().anyRequest().requiresSecure();
}
}
回答by Mahozad
Since TomcatEmbeddedServletContainerFactory
has been removedin Spring Boot 2, use this:
由于TomcatEmbeddedServletContainerFactory
已在 Spring Boot 2 中删除,请使用:
@Bean
public TomcatServletWebServerFactory httpsRedirectConfig() {
return 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);
}
};
}
回答by Arvind Pant
In Spring-Boot, need below dependency
在 Spring-Boot 中,需要以下依赖项
Step 1-
第1步-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Step 2- Just need to do below configurations on application.properties file
步骤 2- 只需要对 application.properties 文件进行以下配置
- server.port=8443
- server.ssl.key.alias=ode-https
- server.ssl.key-store-type=JKS (just for testing i USED JSK, but for production normally use pkcs12)
- server.ssl.key-password=password
- server.ssl.key-store=classpath:ode-https.jks
Step 3- now need to generate a certificate using the above details.
第 3 步 - 现在需要使用上述详细信息生成证书。
keytool -genkey -alias ode-https -storetype JKS -keyalg RSA -keys ize 2048 -validity 365 -keystore ode-https.jks
keytool -genkey -alias ode-https -storetype JKS -keyalg RSA -keys ize 2048 -validity 365 -keystore ode-https.jks
Step 4- move the certificate to resources folder in your program.
第 4 步 - 将证书移动到程序中的资源文件夹。
Step 5- Create config class
第 5 步 - 创建配置类
@Configuration
public class HttpsConfiguration {
@Bean
public ServletWebServerFactory 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(redirectConnector());
return tomcat;
}
@Value("${server.port.http}") //Defined in application.properties file
int httpPort;
@Value("${server.port}") //Defined in application.properties file
int httpsPort;
private Connector redirectConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(httpPort);
connector.setSecure(false);
connector.setRedirectPort(httpsPort);
return connector;
}
}
that's it.
就是这样。
回答by Vladislav Troyan
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().anyRequest().requiresSecure();
}
}
To avoid endless redirect loop (has it on gcloud) add this lines to application properties:
为避免无休止的重定向循环(在 gcloud 上有),将此行添加到应用程序属性中:
server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto