You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

密码找回接口已放行仍遇JWT过期错误,如何分离JWT认证?

解决JWT过期错误,实现密码找回与JWT认证分离

问题根源:你配置的jwtAuthFilter会拦截所有请求(包括已设置permitAll的/user/**路径),当请求携带过期JWT时,过滤器会触发校验并抛出过期错误——permitAll只是授权环节放行,过滤器的执行优先级在授权之前,所以会先触发JWT校验逻辑。

解决方案:修改JwtAuthFilter,跳过无需认证的路径

让JWT过滤器在处理请求前判断路径,若属于放行列表则直接跳过校验,具体实现如下:

假设你的JwtAuthFilter继承自OncePerRequestFilter,修改其doFilterInternal方法:

@Component
public class JwtAuthFilter extends OncePerRequestFilter {

    // 注入你的JwtService、UserDetailsService等依赖
    private final JwtService jwtService;
    private final UserDetailsService userDetailsService;

    // 定义无需JWT认证的路径,和SecurityFilterChain中的配置保持一致
    private final List<String> allowedPaths = Arrays.asList("/api/v1/auth/**", "/user/**");

    public JwtAuthFilter(JwtService jwtService, UserDetailsService userDetailsService) {
        this.jwtService = jwtService;
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestPath = request.getRequestURI();
        
        // 检查当前请求是否属于放行路径,是则直接放行
        boolean isPathAllowed = allowedPaths.stream().anyMatch(path ->
            AntPathMatcher.DEFAULT_PATH_MATCHER.match(path, requestPath)
        );
        
        if (isPathAllowed) {
            filterChain.doFilter(request, response);
            return;
        }

        // 以下是原有的JWT校验逻辑,仅对需要认证的路径执行
        String authHeader = request.getHeader("Authorization");
        String token = null;
        String username = null;

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            token = authHeader.substring(7);
            username = jwtService.extractUsername(token);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (jwtService.isTokenValid(token, userDetails)) {
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        userDetails,
                        null,
                        userDetails.getAuthorities()
                );
                authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }

        filterChain.doFilter(request, response);
    }
}

额外说明

  • 测试时如果请求头携带了过期JWT,即使是密码找回接口,之前的过滤器仍会触发校验;修改过滤器后,会直接跳过这些路径的校验,不再抛出JWT过期错误。
  • 确保allowedPaths中的路径和SecurityFilterChain里permitAll的路径完全一致,使用AntPathMatcher来匹配ant风格的路径(和Spring Security的requestMatchers规则一致)。

内容的提问来源于stack exchange,提问作者Timoumi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:37:40