仅为少数路径禁用过滤器



我如何获得一个过滤器应用于根路径之外的每个请求,除了我想忽略的请求?下面是我的例子:

我有一个Spring安全过滤器,像这样:

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());
}
}

此过滤器填充包含我们所有头信息的CustomApiToken对象,并将其放在Spring Security上下文SecurityContextHolder.getContext().setAuthentication(token)中,以便轻松访问请求控制器上的令牌。

我正在尝试将Springfox添加到项目中,这意味着我想禁用UI和API文档页面的过滤器。

我最初的尝试是在方法中添加一个子句:

@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();
}

然而,我发现这只考虑了第二个子句,因为Spring Security只接受最后一个子句。

I've since try:

@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();
}

但是这使得Springfox URL上的网络过滤器给了我一个缺失的认证令牌错误。

我试着在这里和互联网上寻找,但没有一个例子给我一个可以接受的回应。

在您的自定义AuthenticationFilter中,您可以定义RequestMatcher并在执行逻辑之前使用它,如下所示:

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);
}
}

您可以在自定义过滤器中覆盖OncePerRequestFiltershouldNotFilter方法,以拆分过滤器not_filter逻辑,例如:

public class AuthenticationFilter extends OncePerRequestFilter {
private final List<AntPathRequestMatcher> excludedMatchers;
public AuthenticationFilter (List<AntPathRequestMatcher> excludedMatchers) {
this.excludedMatchers = excludedMatchers;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// your filter logic here
filterChain.doFilter(request, response);
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
return excludedMatchers.stream()
.anyMatch(matcher -> matcher.matches(request));
}
}

默认情况下,此方法总是返回false,因此除非另有指定,否则将对任何请求应用过滤器。

注意,AntPathRequestMatcher的构造函数也可以采用http方法,允许创建更具体的not_filter逻辑,如果您有多个具有相同路径和不同请求方法的端点,但希望只允许对特定端点的自由访问。

最新更新