Spring Security登录验证成功却始终返回403错误求助
问题排查与解决方案
核心问题是你的JsonAuthenticationFilter仅完成了认证请求的解析与验证流程,但未将认证成功的Authentication对象存入SecurityContextHolder,也未完成会话绑定操作,导致后续请求无法识别用户的已认证状态,最终返回403。
具体修复步骤
1. 重写successfulAuthentication方法
UsernamePasswordAuthenticationFilter的默认实现中,successfulAuthentication方法负责将认证结果存入SecurityContext并绑定到会话,但你的自定义过滤器未重写该方法,导致认证成功后关键状态未被持久化。在JsonAuthenticationFilter中添加以下代码:
@Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { // 将认证成功对象存入SecurityContext,供后续过滤器/请求使用 SecurityContextHolder.getContext().setAuthentication(authResult); // 调用父类方法完成会话绑定、SecurityContext持久化等默认逻辑 super.successfulAuthentication(request, response, chain, authResult); // 可在此自定义登录成功响应(比如返回用户信息) response.setContentType("application/json"); response.getWriter().write("{\"message\":\"Login successful\"}"); }
2. 修正过滤器添加位置
直接使用addFilter可能导致自定义过滤器处于过滤器链的错误位置,无法被Spring Security正确识别。修改SecurityConfig中的过滤器添加方式,替换默认的表单登录过滤器:
// 替换原addFilter代码 .addFilterAt(new JsonAuthenticationFilter(authenticationManager), UsernamePasswordAuthenticationFilter.class)
3. 确认会话Cookie的传递
登录请求成功后,响应头中会包含JSESSIONID Cookie,后续请求必须携带该Cookie才能被识别为已认证状态。可以通过浏览器开发者工具或curl命令验证Cookie是否正确返回并被携带。
补充说明
- 你的
Identity类需确保实现了Spring Security的UserDetails接口,日志中显示认证已成功,这部分应该无问题,但可再次确认。 - 会话策略
SessionCreationPolicy.ALWAYS符合你的需求,会确保每次请求都创建或使用已有会话,配合Cookie实现状态保持。
内容的提问来源于stack exchange,提问作者CaptainChameleon
相关产品推荐
相关产品推荐

