Commit 6a777a7f authored by Andy Wilkinson's avatar Andy Wilkinson

Disable HiddenHttpMethodFilter by default

HiddenHttpMethodFilter can be problematic as it causes early
consumption of a request body if the body may contain parameters. This
happens as the filter needs to read the parameters to see if an
_method parameter is present. The filter is only beneficial for web
applications that are the hidden HTTP method functionality but is
potentially detriimental to all applications that are not. As such
we no longer believe that it should be enabled by default and users
should be required to opt in.

Closes gh-16953
parent 2af815f2
...@@ -86,7 +86,7 @@ public class WebFluxAutoConfiguration { ...@@ -86,7 +86,7 @@ public class WebFluxAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class) @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.webflux.hiddenmethod.filter", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "spring.webflux.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() { public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter(); return new OrderedHiddenHttpMethodFilter();
} }
......
...@@ -153,7 +153,7 @@ public class WebMvcAutoConfiguration { ...@@ -153,7 +153,7 @@ public class WebMvcAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class) @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() { public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter(); return new OrderedHiddenHttpMethodFilter();
} }
......
...@@ -302,22 +302,23 @@ class WebFluxAutoConfigurationTests { ...@@ -302,22 +302,23 @@ class WebFluxAutoConfigurationTests {
} }
@Test @Test
void hiddenHttpMethodFilterIsAutoConfigured() { void hiddenHttpMethodFilterIsDisabledByDefault() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(OrderedHiddenHttpMethodFilter.class)); this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HiddenHttpMethodFilter.class));
} }
@Test @Test
void hiddenHttpMethodFilterCanBeOverridden() { void hiddenHttpMethodFilterCanBeOverridden() {
this.contextRunner.withUserConfiguration(CustomHiddenHttpMethodFilter.class).run((context) -> { this.contextRunner.withPropertyValues("spring.webflux.hiddenmethod.filter.enabled=true")
assertThat(context).doesNotHaveBean(OrderedHiddenHttpMethodFilter.class); .withUserConfiguration(CustomHiddenHttpMethodFilter.class).run((context) -> {
assertThat(context).hasSingleBean(HiddenHttpMethodFilter.class); assertThat(context).doesNotHaveBean(OrderedHiddenHttpMethodFilter.class);
}); assertThat(context).hasSingleBean(HiddenHttpMethodFilter.class);
});
} }
@Test @Test
void hiddenHttpMethodFilterCanBeDisabled() { void hiddenHttpMethodFilterCanBeEnabled() {
this.contextRunner.withPropertyValues("spring.webflux.hiddenmethod.filter.enabled=false") this.contextRunner.withPropertyValues("spring.webflux.hiddenmethod.filter.enabled=true")
.run((context) -> assertThat(context).doesNotHaveBean(HiddenHttpMethodFilter.class)); .run((context) -> assertThat(context).hasSingleBean(OrderedHiddenHttpMethodFilter.class));
} }
@Test @Test
......
...@@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon ...@@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration; import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredFilter; import org.springframework.boot.testsupport.web.servlet.MockServletWebServer.RegisteredFilter;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
...@@ -89,6 +90,7 @@ class FilterOrderingIntegrationTests { ...@@ -89,6 +90,7 @@ class FilterOrderingIntegrationTests {
TestRedisConfiguration.class, WebMvcAutoConfiguration.class, SecurityAutoConfiguration.class, TestRedisConfiguration.class, WebMvcAutoConfiguration.class, SecurityAutoConfiguration.class,
SessionAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, SessionAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, HttpEncodingAutoConfiguration.class); PropertyPlaceholderAutoConfiguration.class, HttpEncodingAutoConfiguration.class);
TestPropertyValues.of("spring.mvc.hiddenmethod.filter.enabled:true").applyTo(this.context);
this.context.refresh(); this.context.refresh();
} }
......
...@@ -483,14 +483,14 @@ class WebMvcAutoConfigurationTests { ...@@ -483,14 +483,14 @@ class WebMvcAutoConfigurationTests {
} }
@Test @Test
void hiddenHttpMethodFilterCanBeDisabled() { void hiddenHttpMethodFilterCanBeEnabled() {
this.contextRunner.withPropertyValues("spring.mvc.hiddenmethod.filter.enabled=false") this.contextRunner.withPropertyValues("spring.mvc.hiddenmethod.filter.enabled=true")
.run((context) -> assertThat(context).doesNotHaveBean(HiddenHttpMethodFilter.class)); .run((context) -> assertThat(context).hasSingleBean(HiddenHttpMethodFilter.class));
} }
@Test @Test
void hiddenHttpMethodFilterEnabledByDefault() { void hiddenHttpMethodFilterDisabledByDefault() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(HiddenHttpMethodFilter.class)); this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HiddenHttpMethodFilter.class));
} }
@Test @Test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment