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

Posted

技术标签:

【中文标题】扩展 OncePerRequestFilter 绕过特定的 URL [重复]【英文标题】:Extends OncePerRequestFilter bypass specific URL [duplicate] 【发布时间】:2022-01-20 00:39:34 【问题描述】:

我使用 Spring Boot 2.5.6。我想跳过特定的 URL (/doc.html)。

我创建了一个 JwtAuthenticationTokenFilter 扩展 OncePerRequestFilter

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter 
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException 
        //the logic of authentication

然后我创建 SecurityConfig 扩展 WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    public void configure(WebSecurity web)
            throws Exception 
        web.ignoring()
                .antMatchers(HttpMethod.OPTIONS, "/**")
                .antMatchers("/doc.html");
    

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception 
        httpSecurity
           .csrf().disable()
           .sessionManagement()
               .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
           .authorizeRequests()
               .antMatchers("/doc.html").anonymous()
               .and()
           .requestMatchers().antMatchers("/doc.html");

但是当我访问localhost:8080/doc.html时,/doc.html并没有跳过;

我也尝试在JwtAuthenticationTokenFilter.java 中覆盖shouldNotFilter,但它也不起作用:

@Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException 
        return (
                new AntPathMatcher().match("/doc.html", request.getServletPath()));
    

【问题讨论】:

为什么要创建一个已经存在于 spring security 中的过滤器?请 google 春季安全参考并阅读有关 jwt 的章节 您的过滤器是一个组件,注册为常规过滤器链的一部分。它不是特殊安全过滤器链的一部分,因此会在每个请求上执行。 【参考方案1】:

如果你想绕过多个 URL,你可以在 JwtAuthenticationTokenFilter 中创建一个简单的数组。

例如:

    private static final String[] excluded_urls = 
            "/login",
            "**/doc.html"
    ;

然后重写shouldNotFilter方法:

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException 
        String url = request.getRequestURI();
        return Stream.of(excluded_urls).anyMatch(x -> pathMatcher.match(x, url));
    

在哪里

pathMatcher = new AntPathMatcher();
//can be injected or create wherever required

【讨论】:

【参考方案2】:

您的 JwtAuthenticationTokenFilter 将被 Spring 作为一个组件拾取并包含在过滤器链中,并且不会通过您的 SecurityConfig 自动排除。

因此覆盖shouldNotFilter 似乎是一种有效的方法,应该可以按预期工作。

您可以尝试使用request.getRequestURI() 而不是request.getServletPath() 以确保匹配实际请求路径。详情请见this。

【讨论】:

以上是关于扩展 OncePerRequestFilter 绕过特定的 URL [重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Spring 中使用 OncePerRequestFilter?

java.lang.NoSuchMethodException 尝试使用 OncePerRequestFilter [重复]

SpringBoot:绕过 OncePerRequestFilter 过滤器

Spring的OncePerRequestFilter过滤器

Spring Boot OncePerRequestFilter shouldNotFilter Junit

在 Spring Boot 安全性中,无法跳过登录 url 的 OncePerRequestFilter 过滤器(基本上是在初始登录期间获取 JWT 令牌)