SpringBoot how to set order of Filter without anno

2020-07-22 18:27发布

I'm trying to insert (at first position) a simple custom Cors filter inside the spring filter chain.

If I do it like this

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

it works perfectly I can verify it by putting a breakpoint in Spring's ServletHandler.java where there the line

chain=getFilterChain(baseRequest, target, servlet_holder);

I was just wondering if I wish not to use @Componenent and @Order and instead defining the Filter bean the Application context. How can I set the order of the filters ?

3条回答
乱世女痞
2楼-- · 2020-07-22 18:31

Another alternative is to have your filter implement org.springframework.core.Ordered, and this is the only option if you're using spring webflux (it doesn't have a FilterRegistrationBean):

public class CorsFilter implements Filter, Ordered {
    //...

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE
    }
}

or you can even make it a variable in your filter.

查看更多
Rolldiameter
3楼-- · 2020-07-22 18:38

In case of corsFilter, it is normally required to set the order of this filter to be loaded before springSecurityFilterChain and other filters such as errorPageFilter from spring boot to be laded at the very beginning of the chain. Otherwise CORS support will be broken and the required headers won't be introduced. This can be accomplished in following matter:

@Configuration
public class MyConfiguration {

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://domain1.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(Integer.MIN_VALUE);
        return bean;
    }
}

The bean.setOrder(Integer.MIN_VALUE) will make sure that is is the very first filter loaded. Even if there is other filters such as errorPage filter with order set to Integer.MIN_VALUE(-2147483648).

查看更多
混吃等死
4楼-- · 2020-07-22 18:53

See example: In your class ServletInitializer:

@Bean
 public FilterRegistrationBean requestLogFilter() {
        final FilterRegistrationBean reg = new FilterRegistrationBean(createRequestLogFilter());
        reg.addUrlPatterns("/*");
        reg.setOrder(1); //defines filter execution order
        return reg;
 }

 @Bean
 public RequestLogFilter createRequestLogFilter(){
        return new RequestLogFilter();
 }

the name of my filter is "requestLogFilter"

Warning: Don't use @Component annotation at the class Filter.

查看更多
登录 后发表回答