在您的情况下,最好的选择是使用特定的 path 来避免这些端点,而不是使用自定义注释。原因是 Spring 过滤器提供了很多功能来工作/处理路径和角色。
因此,如果您可以改变方法,可能的解决方案是:
@Component
public class MyGenericFilterBean extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// Do here what you need
filterChain.doFilter(request, response);
}
// Method you should overwrite to avoid the execution of this filter
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
Set<String> avoidFilterForUrls = new HashSet<>(Arrays.asList("/no-filter/**"));
AntPathMatcher pathMatcher = new AntPathMatcher();
return avoidFilterForUrls.stream().anyMatch(p -> pathMatcher.match(p, request.getServletPath()));
}
}
在上面的示例中,对于 URL 以 /no-filter 开头的请求,不会执行过滤器(实际上不会调用 doFilterInternal)。
此时,您需要考虑正确配置您的安全选项。以你为榜样:
http.csrf().disable()
.authorizeRequests()
// List of services do not require authentication
//.antMatchers(GET, "/no-filter/**").permitAll()
// Any other request must be authenticated
.anyRequest().authenticated()
.and()
.addFilterBefore(myGenericFilterBean, MyAuthenticationProcessingFilter.class)
自定义shouldNotFilter 过滤器不会被执行,但考虑到您“正在谈论”MyAuthenticationProcessingFilter,可能有必要将这些端点也包含在“白名单”中,如您所见:
// List of services do not require authentication
// Uncomment and customize with your own ones
//.antMatchers(GET, "/no-filter/**").permitAll()
因为如果您在这些端点中包含“基于角色的安全性”或任何其他安全性,则需要将其删除,因为 Spring 仍会为它们验证安全性。我的意思是,如果您不想将 MyAuthenticationProcessingFilter 应用于这些端点,则不应为它们包含 Spring 安全功能。