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

Spring Security JWT访问端点返回403 Forbidden问题排查

Spring Boot + Security + JWT 403 Forbidden 问题排查与解决

一、核心排查方向

  • 过滤器执行顺序错误:JwtAuthenticationFilter 必须放在 UsernamePasswordAuthenticationFilter 之前,否则权限校验会在JWT认证信息填充前触发
  • 权限配置优先级冲突:Security规则匹配是从上到下、匹配即停止,如果匿名放行规则写在全局认证规则之后,会被覆盖失效
  • JWT解析后未注入Security上下文:解析token成功后,必须将认证对象存入SecurityContextHolder,否则Security无法识别已认证用户
  • CORS配置缺失:跨域场景下,OPTIONS预检请求被拦截会导致实际请求返回403
  • 路径匹配错误:确认/register是否属于/api/v1/auth/**范围,或是否有其他自定义拦截器拦截了请求

二、针对你场景的具体检查步骤

1. 验证过滤器顺序

检查Security配置中过滤器添加方式是否正确:

// 正确写法:将JwtAuthenticationFilter放在UsernamePasswordAuthenticationFilter之前
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

若使用addFilterAfter,会导致权限校验先执行,此时Security上下文无JWT认证信息,直接返回403

2. 检查权限规则顺序

确保匿名放行规则在全局认证规则之前:

http.authorizeHttpRequests(auth -> auth
        // 先放行匿名路径
        .requestMatchers("/api/v1/auth/**").permitAll()
        // 再设置其他路径需认证
        .anyRequest().authenticated()
);

顺序颠倒的话,anyRequest().authenticated()会先匹配所有请求,导致匿名放行规则失效

3. 检查JwtAuthenticationFilter核心逻辑

确认解析token后正确注入Security上下文:

// 在doFilterInternal方法中
Authentication authentication = jwtTokenProvider.getAuthentication(token);
// 必须将认证对象存入上下文,否则Security无法识别
SecurityContextHolder.getContext().setAuthentication(authentication);
// 继续执行后续过滤器链
filterChain.doFilter(request, response);

缺少上下文注入步骤的话,Security会判定请求未认证,返回403

4. 补充CORS配置(跨域场景)

如果是前端跨域请求,需在Security中配置CORS:

http.cors(cors -> cors.configurationSource(corsConfigurationSource()));

// 自定义CORS配置源
private CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(Collections.singletonList("*")); // 生产环境替换为具体域名
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return source;
}

OPTIONS预检请求被拦截会导致实际请求因跨域限制返回403

5. 分析DEBUG日志关键点

重点查看日志中以下内容:

  • 过滤器执行顺序:确认JwtAuthenticationFilter是否在权限校验过滤器前执行
  • SecurityContext状态:请求处理过程中是否存在有效的Authentication对象
  • 请求匹配结果:确认/api/v1/auth/**是否被正确匹配到permitAll规则

三、常见错误示例及修复

错误示例1:过滤器顺序错误

// 错误:将JWT过滤器放在了认证过滤器之后
http.addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

修复:改为addFilterBefore

错误示例2:权限规则顺序错误

http.authorizeHttpRequests(auth -> auth
        .anyRequest().authenticated()
        .requestMatchers("/api/v1/auth/**").permitAll() // 此规则永远不会被匹配
);

修复:调换规则顺序,先写匿名放行规则

错误示例3:未注入Security上下文

// 仅解析token但未存入上下文
Authentication authentication = jwtTokenProvider.getAuthentication(token);
// 缺少SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);

修复:添加上下文注入代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:15:01