From d102e0d7f7b89912df6bdd0741b5ed0d8a9ccc61 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 11 Oct 2018 23:11:47 -0700 Subject: [PATCH] Introduce Ordered Filter and WebFilter interfaces Add `Ordered` variants of `javax.servlet.Filter` and `org.springframework.web.server.WebFilter` mainly so that we can deprecate `FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER`. Closes gh-14793 --- .../security/SecurityProperties.java | 4 +-- .../SecurityAutoConfigurationTests.java | 8 ++--- .../main/asciidoc/spring-boot-features.adoc | 2 +- .../filter/OrderedHiddenHttpMethodFilter.java | 4 +-- .../web/reactive/filter/OrderedWebFilter.java | 35 ++++++++++++++++++ .../AbstractFilterRegistrationBean.java | 3 ++ .../web/servlet/FilterRegistrationBean.java | 5 ++- .../OrderedCharacterEncodingFilter.java | 4 +-- .../web/servlet/filter/OrderedFilter.java | 36 +++++++++++++++++++ .../filter/OrderedFormContentFilter.java | 6 ++-- .../filter/OrderedHiddenHttpMethodFilter.java | 8 ++--- .../filter/OrderedRequestContextFilter.java | 8 ++--- src/checkstyle/checkstyle-suppressions.xml | 2 ++ 13 files changed, 99 insertions(+), 26 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedWebFilter.java create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFilter.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java index a639b3b272b..adc3363c310 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java @@ -25,7 +25,7 @@ import java.util.UUID; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.DispatcherType; -import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.filter.OrderedFilter; import org.springframework.core.Ordered; import org.springframework.util.StringUtils; @@ -58,7 +58,7 @@ public class SecurityProperties implements SecurityPrerequisite { * other filters registered with the container). There is no connection between this * and the {@code @Order} on a WebSecurityConfigurer. */ - public static final int DEFAULT_FILTER_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER + public static final int DEFAULT_FILTER_ORDER = OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100; private final Filter filter = new Filter(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java index 500b55acb42..fd118ce3890 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java @@ -32,7 +32,7 @@ import org.springframework.boot.autoconfigure.orm.jpa.test.City; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.rule.OutputCapture; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; -import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.filter.OrderedFilter; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -85,8 +85,7 @@ public class SecurityAutoConfigurationTests { .getBean("securityFilterChainRegistration", DelegatingFilterProxyRegistrationBean.class) .getOrder()).isEqualTo( - FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - - 100)); + OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100)); } @Test @@ -126,8 +125,7 @@ public class SecurityAutoConfigurationTests { .getBean("securityFilterChainRegistration", DelegatingFilterProxyRegistrationBean.class) .getOrder()).isEqualTo( - FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - - 100)); + OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100)); } @Test diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 9bd90582171..9ba652d1170 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -3063,7 +3063,7 @@ If a specific order is required, you should avoid configuring a Filter that read request body at `Ordered.HIGHEST_PRECEDENCE`, since it might go against the character encoding configuration of your application. If a Servlet filter wraps the request, it should be configured with an order that is less than or equal to -`FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER`. +`OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER`. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedHiddenHttpMethodFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedHiddenHttpMethodFilter.java index 06867ba7ca4..6e592efe6be 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedHiddenHttpMethodFilter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedHiddenHttpMethodFilter.java @@ -26,12 +26,12 @@ import org.springframework.web.filter.reactive.HiddenHttpMethodFilter; * @since 2.0.5 */ public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter - implements Ordered { + implements OrderedWebFilter { /** * The default order is high to ensure the filter is applied before Spring Security. */ - public static final int DEFAULT_ORDER = -10000; + public static final int DEFAULT_ORDER = REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000; private int order = DEFAULT_ORDER; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedWebFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedWebFilter.java new file mode 100644 index 00000000000..d763af776cc --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedWebFilter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.reactive.filter; + +import org.springframework.core.Ordered; +import org.springframework.web.server.WebFilter; + +/** + * An {@link Ordered} {@link org.springframework.web.server.WebFilter}. + * + * @author Phillip Webb + * @since 2.1.0 + */ +public interface OrderedWebFilter extends WebFilter, Ordered { + + /** + * Filters that wrap the request should be ordered less than or equal to this. + */ + int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0; + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/AbstractFilterRegistrationBean.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/AbstractFilterRegistrationBean.java index 6e82483b22a..3926da69fdf 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/AbstractFilterRegistrationBean.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/AbstractFilterRegistrationBean.java @@ -48,7 +48,10 @@ public abstract class AbstractFilterRegistrationBean /** * Filters that wrap the servlet request should be ordered less than or equal to this. + * @deprecated since 2.1.0 in favor of + * {@code OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER} */ + @Deprecated protected static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0; private final Log logger = LogFactory.getLog(getClass()); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistrationBean.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistrationBean.java index ee3c4005af7..08d074fddc6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistrationBean.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistrationBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,7 +45,10 @@ public class FilterRegistrationBean /** * Filters that wrap the servlet request should be ordered less than or equal to this. + * @deprecated since 2.1.0 in favor of + * {@code OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER} */ + @Deprecated public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = AbstractFilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER; private T filter; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedCharacterEncodingFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedCharacterEncodingFilter.java index 982aabd4142..514b55fff3a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedCharacterEncodingFilter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedCharacterEncodingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import org.springframework.web.filter.CharacterEncodingFilter; * @since 2.0.0 */ public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter - implements Ordered { + implements OrderedFilter { private int order = Ordered.HIGHEST_PRECEDENCE; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFilter.java new file mode 100644 index 00000000000..414fabfc740 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFilter.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.servlet.filter; + +import javax.servlet.Filter; + +import org.springframework.core.Ordered; + +/** + * An {@link Ordered} {@link javax.servlet.Filter}. + * + * @author Phillip Webb + * @since 2.1.0 + */ +public interface OrderedFilter extends Filter, Ordered { + + /** + * Filters that wrap the servlet request should be ordered less than or equal to this. + */ + int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0; + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFormContentFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFormContentFilter.java index 8b42e16a50c..63194ca8e02 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFormContentFilter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFormContentFilter.java @@ -16,7 +16,6 @@ package org.springframework.boot.web.servlet.filter; -import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.filter.FormContentFilter; @@ -27,13 +26,12 @@ import org.springframework.web.filter.FormContentFilter; * @author Brian Clozel * @since 2.1.0 */ -public class OrderedFormContentFilter extends FormContentFilter implements Ordered { +public class OrderedFormContentFilter extends FormContentFilter implements OrderedFilter { /** * Higher order to ensure the filter is applied before Spring Security. */ - public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - - 9900; + public static final int DEFAULT_ORDER = REQUEST_WRAPPER_FILTER_MAX_ORDER - 9900; private int order = DEFAULT_ORDER; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedHiddenHttpMethodFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedHiddenHttpMethodFilter.java index cfff3945938..b8c5419da40 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedHiddenHttpMethodFilter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedHiddenHttpMethodFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.boot.web.servlet.filter; -import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.filter.HiddenHttpMethodFilter; @@ -27,13 +26,12 @@ import org.springframework.web.filter.HiddenHttpMethodFilter; * @since 2.0.0 */ public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter - implements Ordered { + implements OrderedFilter { /** * The default order is high to ensure the filter is applied before Spring Security. */ - public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - - 10000; + public static final int DEFAULT_ORDER = REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000; private int order = DEFAULT_ORDER; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedRequestContextFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedRequestContextFilter.java index f2e13e71428..9b7195a2fa4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedRequestContextFilter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedRequestContextFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.boot.web.servlet.filter; -import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.filter.RequestContextFilter; @@ -26,10 +25,11 @@ import org.springframework.web.filter.RequestContextFilter; * @author Phillip Webb * @since 2.0.0 */ -public class OrderedRequestContextFilter extends RequestContextFilter implements Ordered { +public class OrderedRequestContextFilter extends RequestContextFilter + implements OrderedFilter { // Order defaults to after Spring Session filter - private int order = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 105; + private int order = REQUEST_WRAPPER_FILTER_MAX_ORDER - 105; @Override public int getOrder() { diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index b8d737e1ba1..da89bd286db 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -7,6 +7,8 @@ + +