CharacterEncodingFilter不能与Spring Security 3.2.0一起使用

我是Spring MVC框架的新手,我有一个我自己无法解决的问题。 一切都从我的应用程序集成Spring安全性开始,之后,所有来自HTML表单的unicode值都没有被编码(spring安全工作正常)。 我得出的结论是,这可能是因为我的DelegatingFilterProxy被称为链中的第一个filter。

这是我认为会起作用的configuration,但它不是:

1)我正在扩展AbstractSecurityWebApplicationInitializer – 从javadoc:

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

从那个类我也覆盖Spring关于javadoc的SpringSecurityFilterChain方法:

 Invoked before the springSecurityFilterChain is added. 

所以我认为这将是注册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, "/*"); } } 

但是这不起作用。

我累了的另一个select是通过重写getServletFilters()方法来注册通过AbstractAnnotationConfigDispatcherServletInitializer类的filter:

 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}; } } 

但是这也不行。 有没有人遇到同样的问题,或有一些想法如何解决这个问题?

这里是我通过AbstractSecurityWebApplicationInitializer注册编码filter的第一个选项的完整configuration:

 @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); } } 

这是我的第一篇文章,我知道我的文章的格式可以是不愉快的阅读,但下一次应该会更好。

依赖关系:

spring-mvc 3.2.5.RELEASE

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

我正在下面的链接工作: https : //github.com/ajurasz/Manager

有同样的问题。 我的解决scheme是使用一个原始的servletfilter:

 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, "/*"); } 

请注意,这个问题只发生在Tomcat上,而不是Jetty发生。

我们需要在第一次读取请求属性的filter之前添加CharacterEncodingFilter。 有一个securityFilterChain(在metricafilter后面站立),我们可以在里面添加我们的filter。 读取属性的第一个filter(内部安全链)是CsrfFilter,所以我们在它之前放置CharacterEncodingFilter。

简短的解决scheme是:

 @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 } 

我最近遇到了同样的问题,你的第一次尝试实际上是非常接近我最终使用的解决scheme(这里是你的代码,修复):

 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, "/*"); } } 

唯一的区别是为url模式添加filter映射时的第二个参数。 该参数的Javadoc指出:

isMatchAfter – 如果在任何声明的filter映射之后应该匹配给定的filter映射,则为true;如果在获取此FilterRegistration的ServletContext的任何已声明的filter映射之前应该匹配,则为false

所以将其设置为false应该干净地解决您的问题(不涉及任何XML)。

我不知道究竟什么问题,但我从来没有在Spring中configuration这样一个简单的filter。 而是在web.xml正确地做 – 更容易开发,理解和debugging。

  <!-- 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> 

重要:在Spring Securityfilter链之前(即在DelegatingFilterProxy的filter映射之前)configuration此filter的映射。

我用过了

 @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 } 

我不喜欢迄今为止发布的答案,因为要么使用默默无闻的Spring类,要么依赖于实现细节。

在我看来,事情应该通过简单地定义一个@Order高的标准@Bean来工作,所以这是Boot的错误 – 但幸运的是,如果我们使用FilterRegistrationBean而不是一个简单的Filter (我正在使用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; }