web-dev-qa-db-ja.com

CharacterEncodingFilterは、Spring Security 3.2.0と連動しません。

私はSpring MVCフレームワークが初めてであり、自分では解決できない問題を抱えています。 Spring Securityをアプリケーションに統合したときにすべてが始まりました。その後、HTMLフォームのすべてのUnicode値がエンコードされませんでした(Spring Securityは正しく機能します)。これはおそらく、私のDelegatingFilterProxyがチェーンの最初のフィルターとして呼び出されたために起こっているという結論に達しました。

これが機能すると思った私の設定ですが、機能しません:

1)私はAbstractSecurityWebApplicationInitializerを拡張しています-javadocから:

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

そのクラスから、javadocに関してbeforeSpringSecurityFilterChainメソッドもオーバーライドします。

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(List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver =
                new PageableHandlerMethodArgumentResolver();
        pageableHandlerMethodArgumentResolver.setFallbackPageable(new PageRequest(0, 4, new Sort(Sort.Direction.DESC, "id")));

        argumentResolvers.add(pageableHandlerMethodArgumentResolver);
    }
}

依存関係:

spring-mvc3.2.5.RELEASE

spring-security-config、spring-security-web、spring-security-core3.2.0.RELEASE

次のリンクの下でこれに取り組んでいます: https://github.com/ajurasz/Manager

33
ajurasz

同じ問題があります。私の解決策は、生のサーブレットフィルターを使用することでした。

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では発生しないことに注意してください。

11

リクエストプロパティを初めて読み取るフィルターの前にCharacterEncodingFilterを追加する必要があります。 securityFilterChain(2番目、metricaフィルターの後)があり、その中にフィルターを追加できます。プロパティを読み取る最初のフィルター(セキュリティチェーン内)は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
}
59

私は最近同じ問題に遭遇しました、そして、あなたの最初の試みは実際に私が使用することになった解決策に非常に近いです(ここに修正されたあなたのコードがあります):

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パターンのフィルターマッピングを追加するときの2番目の引数です。このパラメーターの Javadoc は次のとおりです。

isMatchAfter-指定されたフィルターマッピングが宣言されたフィルターマッピングの後に一致する必要がある場合はtrue、このFilterRegistrationが取得されたServletContextの宣言されたフィルターマッピングの前に一致することになっている場合はfalse

したがって、falseに設定すると、問題が解決されます(XMLを使用しなくても)。

17
m4rtin

what正確には問題はわかりませんが、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>

重要:このフィルターのマッピングを構成しますbefore Spring Securityフィルターチェーン(つまり、DelegatingFilterProxyのフィルターマッピングの前)。

14
Marcel Stör

利用した

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

あいまいなSpringクラスを使用するか、実装の詳細に依存するため、これまでに投稿された回答が気に入らない。

私の意見では、物事は単に標準@Bean高い@Order、これはブートの障害です-しかし、幸運なことに、プレーンFilterRegistrationBeanの代わりにFilterを使用すると、すべてが期待どおりに動作します(?)(ブート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
Raffaele