java 仅对少数路径禁用筛选器

fslejnso  于 2023-05-05  发布在  Java
关注(0)|答案(2)|浏览(124)

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

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只接受最后一个子句。
从那以后,我尝试过:

@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上的Web过滤器给了我一个缺少身份验证令牌的错误。
我试着在这里四处寻找,在互联网上,但没有一个例子给了我一个可接受的回应。

rjee0c15

rjee0c151#

在你的自定义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);
    }
}
e4yzc0pl

e4yzc0pl2#

你可以在你的自定义过滤器中覆盖OncePerRequestFiltershouldNotFilter方法来分割你的 filternot_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 逻辑,如果你有多个端点具有相同的路径和不同的请求方法,但只允许自由访问特定的一个。

相关问题