SpringBoot:绕过 OncePerRequestFilter 过滤器

Posted

技术标签:

【中文标题】SpringBoot:绕过 OncePerRequestFilter 过滤器【英文标题】:SpringBoot: Bypass OncePerRequestFilter filters 【发布时间】:2019-02-21 12:51:44 【问题描述】:

我有一个基本的 SpringBoot 2.0.5.RELEASE 应用程序。使用 Spring Initializer、JPA、嵌入式 Tomcat、Thymeleaf 模板引擎,并打包为可执行 JAR 文件。

我创建了一个基于自定义 JWT 的安全过滤器 JwtFilter :

@Provider
public class JwtAuthorizationTokenFilter extends OncePerRequestFilter 
...

但我只想为 1 个特定请求/方法绕过此过滤器: "/api/v1/menus",什么时候是POST

但我不知道在WebSecurityConfigurerAdapter中是否可以:

 JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil, tokenHeader);
     httpSecurity
         .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
          .antMatcher("/api/v1/menus")

【问题讨论】:

【参考方案1】:

您可以覆盖OncePerRequestFilter 中的shouldNotFilter 方法,如下所示:

@Provider
public class JwtAuthorizationTokenFilter extends OncePerRequestFilter 
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException 
        return new AntPathMatcher().match("/api/v1/menus", request.getServletPath());
    


【讨论】:

为了包含多个要排除的 url 模式,我们可以在下面使用 hack @Override protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException return (new AntPathMatcher().match("/swagger- ui/**", request.getServletPath()) || new AntPathMatcher().match("/swagger-ui**", request.getServletPath()) || new AntPathMatcher().match("/v3/api -docs/**", request.getServletPath()) );【参考方案2】:

我曾经验证URI路径的HttpServletRequest并使用Filterchain来传递请求,链中的响应。

如下图


public class JwtRequestFilter extends OncePerRequestFilter 

....

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse respone, FilterChain chain) throws ServletException, IOException 

....
String urlPath = request != null ? request.getRequestURI():null;
        String[] splitPath = urlPath != null? urlPath.split("/"):null;
        String currentPath = splitPath!=null?splitPath[splitPath.length-1]:null;
        List<String> allowedPath = Arrays.asList("about","info","authenticate");
        if(currentPath != null && allowedPath.contains(currentPath))
            SecurityContextHolder.getContext().setAuthentication(null);
            chain.doFilter(request, respone);
        
...

汤姆的回答中提到了更好的方法。这很容易。

【讨论】:

以上是关于SpringBoot:绕过 OncePerRequestFilter 过滤器的主要内容,如果未能解决你的问题,请参考以下文章

扩展 OncePerRequestFilter 绕过特定的 URL [重复]

如何使用 springfox 在 Swagger UI 中绕过授权

应用离线时如何绕过 Firebase 身份验证?

如何绕过 CORS 并从 CORS 阻止的 API 获取数据?

SpringFeign客户端发送HTTPS请求绕过认证

SpringBoot基础(三)