我已经创建了两个自定义过滤器,一个负责验证JWT,一个负责处理ExpiredJwtException
。
我已经找到了以正确顺序调用它们的解决方案:多个Spring安全过滤器,以便正确捕获ExpiredJwtException
:
http.antMatcher("jwtRequestFilter/exceptionHandlerFilter/**")
.addFilterBefore(exceptionHandlerFilter, FilterSecurityInterceptor.class)
.antMatcher("jwtRequestFilter/**")
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
经过一些重构之后,我发现让它工作所需要的只是:
http.antMatcher("jwtRequestFilter/**")
.addFilterBefore(exceptionHandlerFilter, FilterSecurityInterceptor.class)
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
但是我不明白antMatcher
方法在这里是如何工作的。antMatcher("jwtRequestFilter/exceptionHandlerFilter/**")
或antMatcher("jwtRequestFilter/**")
需要保持正确的顺序。
如何表达在antMatcher
工作?**
是否意味着链中的其他过滤器,而表达式开头的jwtRequestFilter
是否意味着它是最后一个过滤器?
antMatcher
方法将匹配传入请求的路径,它与过滤器的名称无关。
From Javadoc forantMatcher
:
允许配置HttpSecurity只在匹配提供的ant模式时调用。
这意味着您的自定义过滤器(以及过滤器链的其余部分)只有在传入请求与您提供的ant模式匹配时才会被调用。
考虑这个例子
http
.antMatcher("/admin/**")
.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class)
// ...
如果您请求GET "/admin/home",那么HttpSecurity
将被调用,请求将由customFilter处理。
如果您请求GET "/user/home",那么HttpSecurity
将不会被调用,请求将不会被customFilter处理。
要了解ant风格的路径匹配是如何工作的,请参阅Javadoc中的AntPathMatcher。
你需要为每个端点配置HttpSecurity。
@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);
}
}
参见:
- Java configuration for Multiple HttpSecurity