From 2b3d419e1023bf818443da55990e6c47c4b70016 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 1 Sep 2015 18:25:57 +0100 Subject: [PATCH] Add FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER constant All the filters added explicitly by Spring Boot now have order <= FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER (value 0). There is nothing we can do about the DispatcherServlet and anything else downstream of the filter chain. Fixes gh-3613 --- .../AuthenticationManagerConfiguration.java | 11 +++++---- .../security/SecurityProperties.java | 11 ++++++--- .../web/WebMvcAutoConfiguration.java | 8 ++----- .../SecurityAutoConfigurationTests.java | 24 +++++++++---------- .../embedded/FilterRegistrationBean.java | 7 +++++- .../web/OrderedCharacterEncodingFilter.java | 7 +++--- .../web/OrderedHiddenHttpMethodFilter.java | 5 ++-- .../web/OrderedHttpPutFormContentFilter.java | 5 ++-- 8 files changed, 44 insertions(+), 34 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java index ebaa9d55cf..edaf23f606 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java @@ -69,6 +69,7 @@ public class AuthenticationManagerConfiguration { private static Log logger = LogFactory .getLog(AuthenticationManagerConfiguration.class); + @SuppressWarnings("unused") @Autowired private List dependencies; @@ -111,7 +112,7 @@ public class AuthenticationManagerConfiguration { */ @Order(Ordered.LOWEST_PRECEDENCE - 100) private static class SpringBootAuthenticationConfigurerAdapter extends - GlobalAuthenticationConfigurerAdapter { + GlobalAuthenticationConfigurerAdapter { private final SecurityProperties securityProperties; @@ -151,7 +152,7 @@ public class AuthenticationManagerConfiguration { * */ private static class DefaultInMemoryUserDetailsManagerConfigurer extends - InMemoryUserDetailsManagerConfigurer { + InMemoryUserDetailsManagerConfigurer { private final SecurityProperties securityProperties; @@ -168,7 +169,7 @@ public class AuthenticationManagerConfiguration { User user = this.securityProperties.getUser(); if (user.isDefaultPassword()) { logger.info("\n\nUsing default security password: " + user.getPassword() - + "\n"); + + "\n"); } Set roles = new LinkedHashSet(user.getRole()); withUser(user.getName()).password(user.getPassword()).roles( @@ -196,7 +197,7 @@ public class AuthenticationManagerConfiguration { */ @Component protected static class AuthenticationManagerConfigurationListener implements - SmartInitializingSingleton { + SmartInitializingSingleton { @Autowired private AuthenticationEventPublisher eventPublisher; @@ -218,7 +219,7 @@ public class AuthenticationManagerConfiguration { private void configureAuthenticationManager(AuthenticationManager manager) { if (manager instanceof ProviderManager) { ((ProviderManager) manager) - .setAuthenticationEventPublisher(this.eventPublisher); + .setAuthenticationEventPublisher(this.eventPublisher); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java index fb93153669..89d4ec5845 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.List; import java.util.UUID; +import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.Ordered; import org.springframework.security.config.http.SessionCreationPolicy; @@ -39,7 +40,8 @@ public class SecurityProperties implements SecurityPrerequisite { * useful place to put user-defined access rules if you want to override the default * access rules. */ - public static final int ACCESS_OVERRIDE_ORDER = SecurityProperties.BASIC_AUTH_ORDER - 2; + public static final int ACCESS_OVERRIDE_ORDER = SecurityProperties.BASIC_AUTH_ORDER + - 2; /** * Order applied to the WebSecurityConfigurerAdapter that is used to configure basic @@ -56,9 +58,12 @@ public class SecurityProperties implements SecurityPrerequisite { public static final int IGNORED_ORDER = Ordered.HIGHEST_PRECEDENCE; /** - * Default order of Spring Security's Filter. + * Default order of Spring Security's Filter in the servlet container (i.e. amongst + * other filters registered with the container). There is no connection between this + * and the @Order on a WebSecurityConfigurer. */ - public static final int DEFAULT_FILTER_ORDER = 0; + public static final int DEFAULT_FILTER_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER + - 100; /** * Enable secure channel for all requests. diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index 42aa4d0eb8..1626aeb89c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -49,7 +49,6 @@ import org.springframework.core.Ordered; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistry; import org.springframework.format.datetime.DateFormatter; @@ -97,7 +96,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @ConditionalOnWebApplication @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, - WebMvcConfigurerAdapter.class }) + WebMvcConfigurerAdapter.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter(DispatcherServletAutoConfiguration.class) @@ -137,9 +136,6 @@ public class WebMvcAutoConfiguration { @Autowired private ListableBeanFactory beanFactory; - @Autowired - private ResourceLoader resourceLoader; - @Autowired private HttpMessageConverters messageConverters; @@ -317,7 +313,7 @@ public class WebMvcAutoConfiguration { public ResourceHttpRequestHandler faviconRequestHandler() { ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); requestHandler - .setLocations(this.resourceProperties.getFaviconLocations()); + .setLocations(this.resourceProperties.getFaviconLocations()); return requestHandler; } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java index 0cf2fcef8b..80a6118705 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java @@ -16,6 +16,12 @@ package org.springframework.boot.autoconfigure.security; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.util.List; import org.junit.After; @@ -57,12 +63,6 @@ import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * Tests for {@link SecurityAutoConfiguration}. * @@ -105,7 +105,7 @@ public class SecurityAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); assertEquals( - 0, + FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER-100, this.context.getBean("securityFilterChainRegistration", FilterRegistrationBean.class).getOrder()); } @@ -136,7 +136,7 @@ public class SecurityAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); assertEquals( - 0, + FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER-100, this.context.getBean("securityFilterChainRegistration", FilterRegistrationBean.class).getOrder()); } @@ -364,7 +364,7 @@ public class SecurityAutoConfigurationTests { } private static final class AuthenticationListener implements - ApplicationListener { + ApplicationListener { private ApplicationEvent event; @@ -410,7 +410,7 @@ public class SecurityAutoConfigurationTests { @Configuration protected static class WorkaroundSecurityCustomizer extends - WebSecurityConfigurerAdapter { + WebSecurityConfigurerAdapter { @Autowired private AuthenticationManagerBuilder builder; @@ -435,7 +435,7 @@ public class SecurityAutoConfigurationTests { @Configuration @Order(-1) protected static class AuthenticationManagerCustomizer extends - GlobalAuthenticationConfigurerAdapter { + GlobalAuthenticationConfigurerAdapter { @Override public void init(AuthenticationManagerBuilder auth) throws Exception { @@ -446,7 +446,7 @@ public class SecurityAutoConfigurationTests { @Configuration protected static class UserDetailsSecurityCustomizer extends - WebSecurityConfigurerAdapter { + WebSecurityConfigurerAdapter { private UserDetailsService userDetails; diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/FilterRegistrationBean.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/FilterRegistrationBean.java index c55711bd0b..4fc8e2aa28 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/FilterRegistrationBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/FilterRegistrationBean.java @@ -51,6 +51,11 @@ import org.springframework.util.Assert; */ public class FilterRegistrationBean extends RegistrationBean { + /** + * Filters that wrap the servlet request should have an order less than or equal to this. + */ + public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0; + private static Log logger = LogFactory.getLog(FilterRegistrationBean.class); static final EnumSet ASYNC_DISPATCHER_TYPES = EnumSet.of( @@ -291,7 +296,7 @@ public class FilterRegistrationBean extends RegistrationBean { else { if (servletNames.size() > 0) { logger.info("Mapping filter: '" + registration.getName() - + "' to servlets: " + servletNames); + + "' to servlets: " + servletNames); registration.addMappingForServletNames(dispatcherTypes, this.matchAfter, servletNames.toArray(new String[servletNames.size()])); } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedCharacterEncodingFilter.java b/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedCharacterEncodingFilter.java index a328134302..dd2f9862b0 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedCharacterEncodingFilter.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedCharacterEncodingFilter.java @@ -16,6 +16,7 @@ package org.springframework.boot.context.web; +import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.filter.CharacterEncodingFilter; @@ -25,10 +26,10 @@ import org.springframework.web.filter.CharacterEncodingFilter; * @author Phillip Webb * @since 1.2.1 */ -public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter implements - Ordered { +public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter +implements Ordered { - private int order = Ordered.HIGHEST_PRECEDENCE; + private int order = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 9800; @Override public int getOrder() { diff --git a/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHiddenHttpMethodFilter.java b/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHiddenHttpMethodFilter.java index 550ea1e748..11a911bdf2 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHiddenHttpMethodFilter.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHiddenHttpMethodFilter.java @@ -16,6 +16,7 @@ package org.springframework.boot.context.web; +import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.filter.HiddenHttpMethodFilter; @@ -26,12 +27,12 @@ import org.springframework.web.filter.HiddenHttpMethodFilter; * @since 1.2.4 */ public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter implements - Ordered { +Ordered { /** * The default order is high to ensure the filter is applied before Spring Security. */ - public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10; + public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000; private int order = DEFAULT_ORDER; diff --git a/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHttpPutFormContentFilter.java b/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHttpPutFormContentFilter.java index bce6aeb5e9..5755c21a5a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHttpPutFormContentFilter.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/web/OrderedHttpPutFormContentFilter.java @@ -16,6 +16,7 @@ package org.springframework.boot.context.web; +import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.filter.HttpPutFormContentFilter; @@ -26,12 +27,12 @@ import org.springframework.web.filter.HttpPutFormContentFilter; * @since 1.3.0 */ public class OrderedHttpPutFormContentFilter extends HttpPutFormContentFilter implements - Ordered { +Ordered { /** * Higher order to ensure the filter is applied before Spring Security. */ - public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10; + public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 9900; private int order = DEFAULT_ORDER;