用户输入错误凭证登录时OncePerRequestFilter未触发的原因是什么?
问题原因
核心原因:过滤器链顺序问题
你使用的是Spring Security体系,它内部的过滤器是按固定顺序执行的,你自定义的LoginFilter默认注册位置在用户名密码认证过滤器(UsernamePasswordAuthenticationFilter)之后:
- 用户输入错误凭证时,
UsernamePasswordAuthenticationFilter内部的认证逻辑会直接抛出认证异常,走异常处理流程返回失败响应,请求不会继续传递到后面的自定义过滤器,所以不会触发 - 用户输入正确凭证时,认证通过,请求会继续向后传递,自然就会执行到你的自定义过滤器
补充:代码隐藏问题
你在处理/sign-in路径的逻辑里,直接调用了httpServletRequest.getUserPrincipal().getName():如果请求还没完成认证,getUserPrincipal()会返回null,直接调用getName()会抛出空指针异常,这也是为什么你不能直接把过滤器移到认证流程前面的原因。
解决方案
- 如果你需要在认证逻辑执行前就处理登录请求:手动配置将
LoginFilter插入到UsernamePasswordAuthenticationFilter之前,同时要增加空值判断,避免Principal为null时空指针 - 如果你本身就是要处理认证成功后的逻辑:当前的触发逻辑符合预期,错误凭证不需要走后续处理逻辑,无需调整
- 如果你需要捕获登录失败的事件做额外处理:更合理的方案是自定义实现
AuthenticationFailureHandler,或者监听Spring的AbstractAuthenticationFailureEvent事件,不需要修改过滤器逻辑
内容的提问来源于stack exchange,提问作者midi
相关产品推荐
相关产品推荐

