Spring Boot将HTTP重定向到HTTPS

Ars*_*iev 33 java https redirect http spring-boot

对于基于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
Run Code Online (Sandbox Code Playgroud)

我在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;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试以下时

http://127.0.0.1:9090/
Run Code Online (Sandbox Code Playgroud)

重定向到

https://127.0.0.1:8443/
Run Code Online (Sandbox Code Playgroud)

没有执行.谁遇到过类似的问题?

And*_*son 32

要使Tomcat执行重定向,您需要使用一个或多个安全约束对其进行配置.您可以通过Context使用TomcatEmbeddedServletContainerFactory子类进行后处理来完成此操作.

例如:

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

由于CONFIDENTIAL/*,这将导致Tomcat将每个请求重定向到HTTPS.如果需要更多地控制重定向和未重定向的内容,可以配置多个模式和多个约束.

  • Jetty有类似的方法吗? (8认同)
  • `POST`请求​​未被重定向. (2认同)
  • @Oleksii是的,没错.问题是关于Tomcat的,所以这就是答案所针对的问题.如果您对其他嵌入式服务器感兴趣(并且未使用Spring Security,因此此处的其他答案不适用),您应该询问另一个特定于您正在使用的服务器的问题. (2认同)

Rod*_*ada 27

在应用程序*.properties文件中设置此属性(以及在代理服务器后面运行的HTTPS标头的相应servlet特定配置)并设置Spring Security(例如,使用org.springframework.boot:spring-boot-你的类路径上的starter-security应该足够了:

security.require-ssl=true
Run Code Online (Sandbox Code Playgroud)

现在,出于某种原因,在禁用基本身份验证时(至少在旧版本的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您在代理后面使用Tomcat,您将在应用程序*.properties文件中拥有所有这些属性:

security.require-ssl=true

server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
Run Code Online (Sandbox Code Playgroud)

  • 不建议使用属性'security.require-ssl':安全性自动配置不再可自定义。而是提供您自己的WebSecurityConfigurer bean。 (3认同)
  • 现在不推荐使用security.require-ssl。 (2认同)

Ale*_*sel 10

批准的答案对我来说还不够.

我还必须将以下内容添加到我的Web安全配置中,因为我没有使用默认的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 作为替代方案,您还可以使用:`@Value("${server.http.port}") private int httpPort;`和`@Value("${server.port}") private int httpsPort;`字段,那么你就不必解析 Int,并且代码(imo)看起来会更干净一些。:) (2认同)

rog*_*lad 8

只需2个步骤.

1-在pom.xml中添加spring security dependency

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

2-在应用程序的根包上添加此类.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requiresChannel().anyRequest().requiresSecure();
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

在Spring-Boot中,需要以下依赖

步骤1-

<dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

步骤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
Run Code Online (Sandbox Code Playgroud)

第3步现在需要使用上述详细信息生成证书。

keytool -genkey -alias ode-https -storetype JKS -keyalg RSA -keys ize 2048 -validity 365 -keystore ode-https.jks

步骤4-将证书移至程序中的resources文件夹。

第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;
    }
}
Run Code Online (Sandbox Code Playgroud)

而已。


小智 6

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
        
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    
    http.requiresChannel().anyRequest().requiresSecure();   
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您的应用程序位于负载均衡器或反向代理服务器后面,您需要将以下内容添加到 application.properties 文件中:

server.forward-headers-strategy=NATIVE

这将防止重定向循环。

如果您使用 Tomcat,您可以在 application.properties 文件中配置转发标头的名称:

server.tomcat.remote_ip_header=x-forwarded-for 
server.tomcat.protocol_header=x-forwarded-proto
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅Spring Boot 文档。


Mah*_*zad 5

由于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);
        }
    };
}
Run Code Online (Sandbox Code Playgroud)