You already have a working configuration with filters A and B inserted before the UsernamePasswordAuthenticationFilter , so it should be easy to add another custom filter.
First, you create a filter and declare it as a bean, either annotating the class using @Component , or as @Bean inside the @Configuration class, so it is ready to enter @Autowired .
Now you can enter it as filter A and B and use it. In the "Sort Filters" section of the Spring Security reference documentation, the very first filter in the chain is ChannelProcessingFilter , so to insert a filter before anything else in the Spring security filter chain, you must do this:
@Autowired private CaptchaFilter captchaFilter; @Override protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/iapi/**") .addFilterBefore(captchaFilter, (Class<? extends Filter>) ChannelProcessingFilter.class) .addFilterBefore(filterA, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class) .authorizeRequests() .anyRequest().authenticated(); }
By the way, exceptionHandling() anonymous() and servletApi() not needed, because with the WebSecurityConfigurerAdapter extension they are already enabled, except for anonymous() , when you actually specify more configuration details, since it indicates HttpSecurity javadoc
Keep in mind that the Spring Security Access Point, DelegatingFilterProxy will still run in front of your filter, but this component delegates the request to only the first filter in the chain, which in this case will be CaptchaFilter, so that you really would execute your filter before anything still from Spring Security.
But if you still want the captcha filter to run before DelegatingFilterProxy , there is no way to do this in the Spring security configuration, and you need to declare it in the web.xml .
Update. If you do not want to include the captcha filter in other configurations, you can always add a third configuration, and the configuration class will be as follows:
@EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) public class SpringSecurityConfig { @Configuration @Order(1) public static class CaptchaApiConfigurerAdatper extends WebSecurityConfigurerAdapter { @Autowired private CaptchaFilter captchaFilter; public CaptchaApiConfigurerAdatper() { super(true); } @Override public void configure(WebSecurity web) throws Exception { web .ignoring() .antMatchers("/public/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers() .antMatcher("/iapi/captcha**") .antMatcher("/external/captcha**") .and() .addFilterBefore(captchaFilter, (Class<? extends Filter>) ChannelProcessingFilter.class) .authorizeRequests() .anyRequest().authenticated(); } } @Configuration @Order(2) public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
By the way, one more tip, you can reorganize all the general configuration outside of certain configurations into a main class, for example @EnableGlobalMethodSecurity(securedEnabled = true) AuthenticationManager, WebSecurity to skip security for the public, but for those, the Main class does not extend anything you need @Autowire method declarations.
Although there will be a problem with WebSecurity if you ignore /public/** , the match for HttpSecurity with /public/captcha** will be ignored, so I think you should not reorganize WebSecurity and have a different template in the CaptchaConfig class, so it does not overlap .