我是Spring MVC框架的新手,我遇到了一个我自己无法解决的问题.一切都是在我将spring security与我的应用程序集成后开始的,之后HTML表单中的所有unicode值都没有编码(spring security工作正常).我得出的结论是,这可能是因为我DelegatingFilterProxy
被称为链中的第一个过滤器.
这是我认为可以使用的配置,但它没有:
1)我正在从javadoc扩展AbstractSecurityWebApplicationInitializer:
Registers the DelegatingFilterProxy to use the springSecurityFilterChain() before any other registered Filter.
从那个类我也覆盖了关于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, "/*"); } }
但这不起作用.
我厌倦的另一个选择是通过覆盖getServletFilters()方法通过AbstractAnnotationConfigDispatcherServletInitializer类注册过滤器:
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注册编码过滤器的第一个选项的完整配置:
@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(ListargumentResolvers) { 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
我最近遇到了同样的问题,你的第一次尝试实际上非常接近我最终使用的解决方案(这是你的代码,已修复):
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模式添加过滤器映射时的第二个参数.此参数的Javadoc指出:
isMatchAfter - 如果给定的过滤器映射应在任何声明的过滤器映射之后匹配,则为true;如果在获得此FilterRegistration的ServletContext的任何已声明过滤器映射之前应该匹配,则为false
因此将其设置为false应该干净地解决您的问题(不涉及任何XML).
我们需要在首次读取请求属性的过滤器之前添加CharacterEncodingFilter.有securityFilterChain(排在第二位.在公制过滤器之后),我们可以在其中添加我们的过滤器.读取属性的第一个过滤器(内部安全链)是CsrfFilter,因此我们将CharacterEncodingFilter放在它之前.
简短的解决方案是:
@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中配置这么简单的过滤器.而是做得恰到好处web.xml
- 更容易开发,理解和调试.
<!-- 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>
重要说明:此配置过滤器的映射之前的春季安全过滤器链(过滤器映射之前即DelegatingFilterProxy
).
有同样的问题.我的解决方案是使用原始servlet过滤器:
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中不发生.