Home > other >  Spring Security addFilterAfter method removes the registered filter
Spring Security addFilterAfter method removes the registered filter

Time:02-13

I have a spring project with only two dependencies web & security (for testing purpose)

I am just creating simple filter like that:

public class TestFilter implements Filter {
    private AuthenticationManager authenticationManager;

    public TestFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

And registering this filter in the configuration:

@Configuration
@EnableWebSecurity(debug = true)
public class TestConf extends WebSecurityConfigurerAdapter {

    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAfter(new TestFilter(authenticationManagerBean()), BasicAuthenticationFilter.class);
    }
}

Problem is that,

  • if I use addFilterAfter method, BasicAuthenticationFilter is removed by the Spring, (I can confirm that with console output, @EnableWebSecurity(debug = true) this annotation prints all security filters)

Here is the log:

o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@158f4cfe, org.springframework.security.web.context.SecurityContextPersistenceFilter@1174a305, org.springframework.security.web.header.HeaderWriterFilter@2b037cfc, org.springframework.security.web.csrf.CsrfFilter@76db540e, org.springframework.security.web.authentication.logout.LogoutFilter@13741d5a, com.....security.filter.TestFilter@35f639fa, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1866da85, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@2ec3633f, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5aaaa446, org.springframework.security.web.session.SessionManagementFilter@19ee1ae6, org.springframework.security.web.access.ExceptionTranslationFilter@4eb1c69]
  • if i don't register my custom filter, then I can see BasicAuthenticationFilter: security.web.authentication.www.BasicAuthenticationFilter

Here is the configuration class:

@Configuration
@EnableWebSecurity(debug = true)
public class ProjectBeanConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }
}

Here is the log:

 o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@704641e3, org.springframework.security.web.context.SecurityContextPersistenceFilter@750ff7d3, org.springframework.security.web.header.HeaderWriterFilter@42b6d0cc, org.springframework.security.web.csrf.CsrfFilter@5c7668ba, org.springframework.security.web.authentication.logout.LogoutFilter@459b187a, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@741f8dbe, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@7fd26ad8, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@2f00f851, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@7a8406c2, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2620e717, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3d37203b, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@4207609e, org.springframework.security.web.session.SessionManagementFilter@3f4f5330, org.springframework.security.web.access.ExceptionTranslationFilter@e042c99, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@17d32e9b]

What can be the reason?

CodePudding user response:

It is because you define your own WebSecurityConfigurerAdapter which causes the default security configuration defined by spring-boot does not take effect. And in your configuration , you never enable BasicAuthenticationFilter. So try the following should fix the problem :

@Override
protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()
        .and().addFilterAfter(new TestFilter(authenticationManagerBean()), BasicAuthenticationFilter.class);
 }

If you want to keep the default configuration provided by spring-boot and add a TestFilter on top of it , you have to configure it manually :

@Override
protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic()
        .and().addFilterAfter(new TestFilter(authenticationManagerBean()), BasicAuthenticationFilter.class);
 }

You can find the default configuration at here and its javadoc also already mentioned such behaviour :

The default configuration for web security. It relies on Spring Security's content-negotiation strategy to determine what sort of authentication to use. If the user specifies their own WebSecurityConfigurerAdapter or SecurityFilterChain bean, this will back-off completely and the users should specify all the bits that they want to configure as part of the custom security configuration.

  • Related