Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Spring Security do automatic filter Injection?

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.

like image 870
Steven Avatar asked Aug 08 '16 03:08

Steven


2 Answers

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;
}
like image 117
shobull Avatar answered Nov 04 '22 05:11

shobull


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:

  1. CustomFilter
  2. FilterChainProxy(SessionFilter, BasicAuthFilter, etc)
  3. OtherCustomFilter
  4. OtherFilterChainProxy(OAuth2Filter, etc)

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.

like image 35
Ulises Avatar answered Nov 04 '22 05:11

Ulises