Filter order in spring-boot
Guys from Spring helped again. See https://github.com/spring-projects/spring-boot/issues/1640 and https://jira.spring.io/browse/SEC-2730
Spring Security doesn't set an order on the Filter bean that it
creates. This means that, when Boot is creating a
FilterRegistrationBean for it, it gets the default order which is
LOWEST_PRECEDENCE.If you want your own Filter to go after Spring Security's you can
create your own registration for Spring Security's filter and specify
the order.
So the answer to my question is:
@Bean
public FilterRegistrationBean securityFilterChain(@Qualifier(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) Filter securityFilter) {
FilterRegistrationBean registration = new FilterRegistrationBean(securityFilter);
registration.setOrder(Integer.MAX_VALUE - 1);
registration.setName(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
return registration;
}
@Bean
public FilterRegistrationBean userInsertingMdcFilterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
UserInsertingMdcFilter userFilter = new UserInsertingMdcFilter();
registrationBean.setFilter(userFilter);
registrationBean.setOrder(Integer.MAX_VALUE);
return registrationBean;
}
SpringBoot how to set order of Filter without annotation
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.
Controlling the order of non-security Filters in a Spring Boot app using Spring Security
You may set order of filter using @Order annotation. It has default value Integer.MAX_VALUE
this way your filter will be executed last(lower values have higher priority). Here is an example:
@Order
@Component
public class TestFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest, servletResponse);
}
}
Spring Security is a single physical Filter
but delegates processing to a chain of internal filters such as: SecurityContextPersistenceFilter, RememberMeAuthenticationFilter, AnonymousAuthenticationFilter, etc. The security filter is installed at a position defined by SecurityProperties.DEFAULT_FILTER_ORDER which is set to -100
. So any filter with order higher than -100
will be executed after FilterChainProxy (concrete class of spring security filter)
For example:
@Order(SecurityProperties.DEFAULT_FILTER_ORDER-1)
@Component
public class BeforeSecurityFilter implements Filter
Will be executed before security filter and:
@Order(SecurityProperties.DEFAULT_FILTER_ORDER+1)
@Component
public class AfterSecurityFilter implements Filter
Will be executed after security filter
Ordering custom filters in Spring Security configuration
The antMatcher
method will match the path of incoming requests, it is not related to the names of the filters.
From the Javadoc for antMatcher
:
Allows configuring the HttpSecurity to only be invoked when matching the provided ant pattern.
This means that your custom filters (and the rest of the filter chain) will only be invoked if the incoming request matches the ant pattern that you have provided.
Consider this example
http
.antMatcher("/admin/**")
.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class)
// ...
If you make a request to GET "/admin/home", then HttpSecurity
will be invoked the request will be processed by customFilter.
If you make a request to GET "/user/home", then HttpSecurity
will not be invoked the request won't be processed by customFilter.
To understand how ant-style path matching works, see the Javadoc for AntPathMatcher.
Related Topics
Calling Getters on an Object VS. Storing It as a Local Variable (Memory Footprint, Performance)
When Does the Main Thread Stop in Java
Exact Difference Between Charsequence and String in Java
How to Make Cartesian Product with Java 8 Streams
Stringbuilder/Stringbuffer VS. "+" Operator
JPA @Onetoone with Shared Id -- How to Do This Better
Fetch First Element of Stream Matching the Criteria
Comparing the Values of Two Generic Numbers
How to Use Collections.Sort() in Java
Gradle - Getting the Latest Release Version of a Dependency
How to Intercept a Method Invocation with Standard Java Features (No Aspectj etc)
Cannot Assign Requested Address Using Serversocket.Socketbind
How to Zip a Folder Itself Using Java
How to Tell Spring Boot Which Main Class to Use for the Executable Jar
In Java, How to Know Whether a Class Has Already Been Loaded