Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CharacterEncodingFilter don't work together with Spring Security 3.2.0

I'm new to Spring MVC framework and I have got an issue that I can not resolve by myself. Everything started when I integrated spring security with my application, after that all unicode values from HTML form were not encoded (spring security works correctly). I came to conclusion that this is happening probably because my DelegatingFilterProxy is called as the first filter in the chain.

Here is my configuration that I thought will work, but it doesn't:

1)I'm extending AbstractSecurityWebApplicationInitializer - from javadoc:

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

From that class I also override beforeSpringSecurityFilterChain method which regarding to javadoc:

Invoked before the springSecurityFilterChain is added. 

So I thought this will 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 this do not work.

Another option I tired was to register filter through AbstractAnnotationConfigDispatcherServletInitializer class by overriding 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 this do not work neither. Does anyone come across the same issue or have got some ideas how to resolve this?

Here is my full configuration for the first option where I'm registering 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'm working on this under following link: https://github.com/ajurasz/Manager

like image 619
ajurasz Avatar asked Dec 31 '13 21:12

ajurasz


People also ask

Which authorization levels are supported by Spring Security?

1. Overview. Simply put, Spring Security supports authorization semantics at the method level. Typically, we could secure our service layer by, for example, restricting which roles are able to execute a particular method — and test it using dedicated method-level security test support.

Will Spring Security secures all the applications?

If Spring Security is on the classpath, Spring Boot automatically secures all HTTP endpoints with “basic” authentication. However, you can further customize the security settings. The first thing you need to do is add Spring Security to the classpath.


1 Answers

We need to add CharacterEncodingFilter before filters who read request properties for the first time. There is securityFilterChain (stands second. after metrica filter) and we can add our filter inside it. The first filter (inside security chain) who reads properties is CsrfFilter, so we place CharacterEncodingFilter before it.

The short solution is:

@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 } 
like image 63
Alexandr Latushkin Avatar answered Oct 04 '22 06:10

Alexandr Latushkin