Issue
How do I get a filter to apply to every request off the root path except for ones I want to ignore? Here's my example:
I have a Spring Security filter like so:
private static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().antMatcher("/**")
.addFilterBefore(new AuthenticationFilter(), BasicAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity web) {
web.ignoring().requestMatchers(SecurityServletRequestMatchers.servletIgnoreAuthMatcher());
}
}
This filter populates a CustomApiToken object which contains all of our header information and puts it in the spring security context SecurityContextHolder.getContext().setAuthentication(token)
for easy access to the token on the requesting controller.
I'm trying to add springfox to the project, which means I want to disable the filter for the UI and api docs pages.
My original attempt was to add a clause to the method:
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().antMatcher("/**")
.addFilterBefore(new AuthenticationFilter(), BasicAuthenticationFilter.class);
http.requestMatcher(SecurityServletRequestMatchers.servletIgnoreAuthMatcher()).headers() //.servletIgnoreAuthMatchers has all the swagger urls also
.defaultsDisabled()
.disable()
.authorizeRequests()
.anyRequest().authenticated();
}
However I discovered that this only takes the second clause into account due to spring security only accepting the last clause.
I've since tried:
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/**")
.addFilterBefore(new AuthenticationFilter(), BasicAuthenticationFilter.class)
.requestMatcher(SecurityServletRequestMatchers.servletIgnoreAuthMatcher()).headers()
.defaultsDisabled()
.disable()
.authorizeRequests()
.anyRequest().authenticated();
}
But that left the webfilter on the springfox url giving me a missing authentication token error.
I've tried looking around here, and on the internet, but none of the examples have given me an acceptable response yet.
Solution
In your custom AuthenticationFilter
you can define a RequestMatcher
and use it before doing your logic, like so:
public class AuthenticationFilter extends OncePerRequestFilter {
private final RequestMatcher ignoredPaths = new AntPathRequestMatcher("/swagger-ui");
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
if (this.ignoredPaths.matches(request)) {
filterChain.doFilter(request, response);
return;
}
// do your logic
filterChain.doFilter(request, response);
}
}
Answered By - Marcus Hert da Coregio
Answer Checked By - Candace Johnson (JavaFixing Volunteer)