CharacterEncodingFilter does not work with Spring Security 3.2.0

I am new to Spring MVC framework and I have a problem that I cannot solve on my own. It all started when I integrated the Spring protection with my application, after which all the unicode values ​​from the HTML form were not encoded (spring security works correctly). I came to the conclusion that this is probably because my DelegatingFilterProxy is called the first filter in the chain.

Here is my configuration, which I thought would work, but it is not:

1) I am extending AbstractSecurityWebApplicationInitializer - from javadoc:

 Registers the DelegatingFilterProxy to use the springSecurityFilterChain() before any other registered Filter. 

From this class, I also override the beforeSpringSecurityFilterChain method, which concerns javadoc:

 Invoked before the springSecurityFilterChain is added. 

So, I thought this would be the best place to register CharacterEncodingFilter:

 public class MessageSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { @Override protected void beforeSpringSecurityFilterChain(ServletContext servletContext) { FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter()); characterEncodingFilter.setInitParameter("encoding", "UTF-8"); characterEncodingFilter.setInitParameter("forceEncoding", "true"); characterEncodingFilter.addMappingForUrlPatterns(null, true, "/*"); } } 

But that does not work.

Another option that I'm tired of is registering the filter through the AbstractAnnotationConfigDispatcherServletInitializer class by overriding the getServletFilters () method:

 public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { //{!begin addToRootContext} @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { SecurityConfig.class, DatabaseConfig.class, InternationalizationConfig.class }; } //{!end addToRootContext} @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebAppConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } @Override protected Filter[] getServletFilters() { CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setEncoding("UTF-8"); characterEncodingFilter.setForceEncoding(true); return new Filter[] { characterEncodingFilter}; } } 

But that does not work. Does anyone encounter the same problem or have some ideas on how to resolve this?

Here is my complete configuration for the first parameter, where I register an encoding filter through AbstractSecurityWebApplicationInitializer:

 @Order(1) public class MessageSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { @Override protected void beforeSpringSecurityFilterChain(ServletContext servletContext) { FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter()); characterEncodingFilter.setInitParameter("encoding", "UTF-8"); characterEncodingFilter.setInitParameter("forceEncoding", "true"); characterEncodingFilter.addMappingForUrlPatterns(null, true, "/*"); } } @Order(2) public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { //{!begin addToRootContext} @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { SecurityConfig.class, DatabaseConfig.class, InternationalizationConfig.class }; } //{!end addToRootContext} @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebAppConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } } @EnableWebMvc //@Import(value = {DatabaseConfig.class, InternationalizationConfig.class, SecurityConfig.class}) @ComponentScan(basePackages = {"com.ajurasz.controller", "com.ajurasz.service", "com.ajurasz.model"}) @Configuration public class WebAppConfig extends WebMvcConfigurerAdapter { @Bean public UrlBasedViewResolver viewResolver() { UrlBasedViewResolver urlBasedViewResolver = new UrlBasedViewResolver(); urlBasedViewResolver.setViewClass(TilesView.class); urlBasedViewResolver.setContentType("text/html;charset=UTF-8"); return urlBasedViewResolver; } @Bean public TilesConfigurer tilesConfigurer() { TilesConfigurer tilesConfigurer = new TilesConfigurer(); tilesConfigurer.setDefinitions(new String[] {"/WEB-INF/tiles.xml"}); return tilesConfigurer; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/**"); registry.addResourceHandler("/documents/**").addResourceLocations("/WEB-INF/pdfs/documents/**"); } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver = new PageableHandlerMethodArgumentResolver(); pageableHandlerMethodArgumentResolver.setFallbackPageable(new PageRequest(0, 4, new Sort(Sort.Direction.DESC, "id"))); argumentResolvers.add(pageableHandlerMethodArgumentResolver); } } 

Dependencies:

spring -mvc 3.2.5.RELEASE

spring -security-config, spring -security-web, spring -security-core 3.2.0.RELEASE

I am working on this at the following link: https://github.com/ajurasz/Manager

+30
spring-java-config spring-mvc spring-security
Dec 31 '14 at 21:43
source share
6 answers

Have the same problem. My solution was to use a raw servlet filter:

 public void onStartup(ServletContext servletContext) throws ServletException { FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encoding-filter", new CharacterEncodingFilter()); encodingFilter.setInitParameter("encoding", "UTF-8"); encodingFilter.setInitParameter("forceEncoding", "true"); encodingFilter.addMappingForUrlPatterns(null, true, "/*"); } 

Please note that this problem only occurs with Tomcat, but not with Jetty.

+12
Jan 20 '14 at 9:01
source share

We need to add a CharacterEncodingFilter before the filters that read query properties for the first time. There is securityFilterChain (it is second after the metric filter), and we can add our filter to it. The first filter (inside the security chain) that reads the properties is CsrfFilter, so before that it puts CharacterEncodingFilter.

Short decision:

 @Configuration @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding("UTF-8"); filter.setForceEncoding(true); http.addFilterBefore(filter,CsrfFilter.class); //rest of your code } //rest of your code } 
+48
Apr 14 '14 at 2:57
source share

I have run into the same problem lately, and your first attempt is actually very close to the solution I used (here your code is fixed):

 public class MessageSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { @Override protected void beforeSpringSecurityFilterChain(ServletContext servletContext) { FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter()); characterEncodingFilter.setInitParameter("encoding", "UTF-8"); characterEncodingFilter.setInitParameter("forceEncoding", "true"); characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*"); } } 

The only difference is the second argument when adding a filter for URL patterns. In Javadoc, for this parameter, it says:

isMatchAfter - true if the specified filter map must be matched after any declared filter mappings, and false if it must be matched before any declared ServletContext filter mappings from which this filter registration was obtained.

So setting it to false should cleanly solve your problem (without any XML).

+16
Apr 30 '14 at 21:08
source share

I don’t know what the problem is, but I would never have configured such a simple filter inside Spring. Rather do it right in web.xml - it's easier to develop, understand, and debug.

  <!-- Hint: http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q8 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 

Important: configure this filter mapping before the Spring filter chain (i.e. before displaying the filter for DelegatingFilterProxy ).

+9
Dec 31 '14 at 23:12
source share

I used

 @Configuration @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding("UTF-8"); filter.setForceEncoding(true); http.addFilterBefore(filter,CsrfFilter.class); //rest of your code } //rest of your code } 
+3
Dec 12 '15 at 3:45
source share

I don't like the answers posted so far because they either use the implicit Spring classes or rely on implementation details.

In my opinion, everything should work just by defining a standard @Bean with a high @Order , so this is a loading error - but, fortunately, everything works as expected (?) If we use a FilterRegistrationBean instead of a simple Filter (I use Boot 1.1. 5):

 @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); registrationBean.setFilter(characterEncodingFilter); characterEncodingFilter.setEncoding("UTF-8"); characterEncodingFilter.setForceEncoding(true); registrationBean.setOrder(Integer.MIN_VALUE); registrationBean.addUrlPatterns("/*"); return registrationBean; } 
+2
Sep 11 '14 at 19:10
source share



All Articles