I have a spring-boot application (spring-boot v1.3.3.RELEASE) that uses spring-security core v4.1.1.RELEASE.
It seems that if I make a custom filter bean by extending OncePerRequestFilter
or GenericFilterBean
, my filter will automatically be added to the filter chain, regardless of whether or not I call addFilter()
on the HttpSecurity
object that's passed to configure()
in a custom WebSecurityConfigurerAdapter
class.
Here is the custom filter code:
@Component
public class CustomFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// custom filter code here
}
}
Here is the abbreviated security configuration code:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// not adding the custom filter here
http.authorizeRequests()
.antMatchers("/api/login/**").permitAll()
.anyRequest().authenticated();
}
}
What I have observed is that all requests, even to /api/login
, will pass through CustomFilter
, even though I didn't add it to the filter chain anywhere. If I declare CustomFilter
without any @Configuration
or @Bean
annotations, it will not be added to the filter chain unless I explicitly tell it to in the SecurityConfiguration
class.
My question: Is this the intended behavior? If so, why? It would seem to me that adding a filter automatically to the filter chain is dangerous, for lack of a better word--each request passes through the filter regardless of what I have specified in SecurityConfiguration
.
Yes, Spring Boot documentations says following: To add a Servlet, Filter, or Servlet *Listener provide a @Bean definition for it.
(source)
You can manually disable filter using:
@Bean
public FilterRegistrationBean registration(@Qualifier("customFilter") Filter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
The main difference is that when you add a regular filter like you mention it gets added to the main servlet container filter chain, and when you add the filter through HttpSecurity.addFilter(Filter)
it's being added to the security FilterChainProxy
. The filter chain proxy is basically it's own filter chain within a Filter
implementation that delegates to the filters inside the proxy. So your Filter doesn't interfere with the security Filters.
To illustrate a bit, it would be something like this:
So the servlet container sees 4 Filters. 2 Custom Filters and 2 Spring Security configurations. When it gets to the FilterChainProxy, the proxy just delegates to first filter inside the internal chain, if and only if your configuration allows that security configuration to intercept the request URL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With