使用JWT的Spring认证返回403错误排查求助
排查Spring Security+JWT登录时403 Forbidden的问题
我之前在做Spring Security结合JWT的REST认证时,也碰到过一模一样的403问题,当时排查了好半天😂。结合你的情况,咱们从几个常见的坑入手:
1. 确认/login端点是否被正确放行
Spring Security默认会拦截所有请求,如果你没明确把/login设置为允许匿名访问,就会直接返回403。你需要在configure(HttpSecurity http)方法里,给/login端点加上permitAll()规则,还要注意请求方法(一般登录是POST请求):
.authorizeRequests() .antMatchers(HttpMethod.POST, "/login").permitAll() // 明确放行POST类型的/login请求 .anyRequest().authenticated();
如果你的/login是GET请求(不推荐,但也有可能),要对应修改HttpMethod。
2. 关闭CSRF防护
REST API使用JWT认证时,CSRF防护是不需要的(CSRF主要针对浏览器表单提交场景)。如果没关闭CSRF,POST请求到/login会被Spring Security拦截,返回403。记得在配置里加上:
http.csrf().disable();
3. 检查过滤器顺序是否正确
如果你自定义了JWT认证过滤器,一定要确保登录请求不会被它提前拦截。两种解决思路:
- 方法一:调整过滤器顺序:把JWT过滤器放在
UsernamePasswordAuthenticationFilter之后,让登录请求先走到登录逻辑,再执行JWT验证:
// 将JWT过滤器放在用户名密码认证过滤器之后执行 http.addFilterAfter(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
- 方法二:在JWT过滤器里放行/login:在过滤器的
doFilterInternal方法里判断请求路径,是/login就直接跳过验证:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String path = request.getRequestURI(); if ("/login".equals(path)) { filterChain.doFilter(request, response); return; } // 剩下的JWT令牌验证逻辑 }
4. 开启Spring Security日志排查细节
如果上面的方法都没解决,建议开启Spring Security的DEBUG级别日志,这样能看到具体是哪个拦截器返回了403,以及拦截的原因。在你的application.yml(或application.properties)里添加:
logging: level: org.springframework.security: DEBUG
启动项目后调用/login接口,查看控制台日志,会有详细的拦截过程记录,比如“FilterSecurityInterceptor: Denied access to authenticated user”之类的信息,能帮你精准定位问题。
最后检查几个小细节
- 确认你的/login请求的
Content-Type是否正确(比如application/json),如果后端期望JSON格式,而你传了表单格式,可能会导致认证异常; - 检查有没有其他自定义拦截器、过滤器(比如跨域拦截器、日志拦截器)干扰了请求,导致请求还没到Spring Security就被拦截了。
内容的提问来源于stack exchange,提问作者ruizing
相关产品推荐
相关产品推荐

