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 中绕过授权