1

I have created two custom filters, one responsible for validating JWT and one for handling ExpiredJwtException.

I have found solution to invoke them in the right order there: Multiple Spring Security filters, so that the ExpiredJwtException is properly caught:

http.antMatcher("jwtRequestFilter/exceptionHandlerFilter/**")
                .addFilterBefore(exceptionHandlerFilter, FilterSecurityInterceptor.class)
                .antMatcher("jwtRequestFilter/**")
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

After some refactoring it turned out that all I need to make it work is:

http.antMatcher("jwtRequestFilter/**")
                .addFilterBefore(exceptionHandlerFilter, FilterSecurityInterceptor.class)
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

But I don't get how does the antMatcher method work here. Either antMatcher("jwtRequestFilter/exceptionHandlerFilter/**") or antMatcher("jwtRequestFilter/**") is needed to remain correct order.

How does expressions in antMatcher work? Does ** means other filters in the chain and jwtRequestFilter on the beginning of the expression means it is last filter?

V3x
  • 13
  • 4

2 Answers2

1

The antMatcher method will match the path of incoming requests, it is not related to the names of the filters.

From the Javadoc for antMatcher:

Allows configuring the HttpSecurity to only be invoked when matching the provided ant pattern.

This means that your custom filters (and the rest of the filter chain) will only be invoked if the incoming request matches the ant pattern that you have provided.

Consider this example

http
    .antMatcher("/admin/**")
    .addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class)
    // ...

If you make a request to GET "/admin/home", then HttpSecurity will be invoked the request will be processed by customFilter.

If you make a request to GET "/user/home", then HttpSecurity will not be invoked the request won't be processed by customFilter.

To understand how ant-style path matching works, see the Javadoc for AntPathMatcher.

  • I have played a bit with code to see its behavior with different patterns and it turns out that I can put almost anything there, for example `"randomString"`, `"/randomString"` and `"randomString/**"` still works, but if I wirte `"/**"` or remove completely `antMatcher` filtering order breaks. Maybe reason for this behavior is related to something else in project. Thanks for help. – V3x Feb 19 '21 at 12:21
  • I've found that it applies the filter regardless of whether the path matches the pattern. – MiguelMunoz Nov 10 '22 at 05:47
0

You need HttpSecurity configs per endpoint.

@Configuration
@Order(1)
public class JwtExceptionHandleConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        final Filter exceptionHandlerFilter = new ExceptionHandlerFilter();

        http.antMatcher("/jwtRequestFilter/exceptionHandlerFilter/**")
            .addFilterBefore(exceptionHandlerFilter, FilterSecurityInterceptor.class);
    }

}
@Configuration
@Order(2)
public class JwtRequestConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        final Filter jwtRequestFilter = new JwtRequestFilter();
        final Filter exceptionHandlerFilter = new ExceptionHandlerFilter();

        http.antMatcher("/jwtRequestFilter/**")
            .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
            .addFilterBefore(exceptionHandlerFilter, FilterSecurityInterceptor.class);

    }
}

See also:

Tristan
  • 8,733
  • 7
  • 48
  • 96