I have experienced a strange problem while trying to configure HTTP security by using WebSecurityConfigurerAdapter. Here is the full configuration class I tried so far:
@Slf4j @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) @ConditionalOnProperty(name = "module.client.security.enabled") public class SecurityConfig extends WebSecurityConfigurerAdapter { @Value("${management.endpoints.web.base-path}") private String managementEndpoint; @Autowired private List<ModuleProperties> moduleProperties; @Override public void configure(WebSecurity web) { web.ignoring() .antMatchers(this.managementEndpoint + "/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http.httpBasic().disable(); http.formLogin().disable(); // FIXME also doesn't work because of the later http.requestMatchers().antMatchers() calls http.authorizeRequests() .antMatchers("/**").anonymous(); http.requestMatchers() .antMatchers("/app/**") .and() .addFilterBefore(new ClientResolveFilter(), FilterSecurityInterceptor.class); }
What I would like to do is actually enabling anonymous authentication for all endpoints — to prevent NullPointerExceptions when operating on SecurityContextHolder — Plus, enabling/adding a custom filter to only a subset or different endpoint path which is /app/**
in this case.
I expected the above code would work but what exactly happens is the AnonymousAuthenticationFilter disabled for all and both filters only work for the path /app/**
only.
If I remove the http.requestMatchers().antMatchers("/app/**")
part, then AnonymousAuthenticationFilter works for all paths as normal. I suspect that the second .antMatchers("/app/**")
call kinda replaces the former one or substitutes it implicitly which doesn’t make sense to me, but I could be wrong.
I tried diving into the source but still confused and cannot find a clean solution to make it work as my expectation. Any ideas and help will be appreciated.
Cheers!
EDIT: I’m using Spring Boot 2.5.2 and the Spring Security version is 5.5.1
Advertisement
Answer
After @Dickson’s advice, I found a special bean called FilterRegistrationBean
provided by spring boot.
Thus, I configured it as a bean which applies a specific servlet filter to only configured paths:
@Bean public FilterRegistrationBean<ClientResolveFilter> clientResolveFilter(){ final FilterRegistrationBean<ClientResolveFilter> frb = new FilterRegistrationBean<>(); frb.setFilter(new ClientResolveFilter()); frb.addUrlPatterns("/app/*"); return frb; }
This solution worked perfectly for my requirement.
Pay attention to that the path string is not an ant matcher now — must be written with single /app/*
instead of double /app/**
— it’s actually the pattern when we manually configured web.xml file like in the old days 🙂