Spring Security /login端点返回404:无静态资源login问题排查
问题分析与解决方案
针对你遇到的Spring Security认证后返回404、Actuator端点静态资源找不到的问题,结合Spring Boot 3.2.2 + Spring Security 6.2.1的版本特性,给出以下排查方向和解决方法:
1. 自定义认证过滤器未终止请求流转
核心问题:正确认证后,请求未被终止,被转发到Spring的静态资源处理器,导致找不到login静态资源返回404;而错误认证时,失败处理器直接返回了401,终止了请求流转。
解决方法:
在自定义AuthenticationFilter的成功处理器中,明确终止请求,不要让请求继续向下传递到DispatcherServlet:
@Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { // 生成并写入JWT到响应 jwtGeneratorFilter.generateToken(response, authResult); // 直接设置响应状态并结束请求 response.setStatus(HttpServletResponse.SC_OK); response.getWriter().flush(); // 不要调用chain.doFilter(request, response); 避免请求继续流转 }
同时,在SecurityConfig中禁用默认表单登录(避免默认/login端点冲突):
@Override protected void configure(HttpSecurity http) throws Exception { http.csrf(csrf -> csrf.disable()) // 禁用默认表单登录,避免与自定义/login端点冲突 .formLogin(form -> form.disable()) .authorizeHttpRequests(auth -> auth .requestMatchers("/login", "/actuator/**").permitAll() .anyRequest().authenticated() ) .addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterAfter(jwtValidatorFilter(), CustomAuthenticationFilter.class); }
2. Actuator httptrace端点配置问题
Spring Boot 3.x中httptrace端点默认禁用,需手动开启并放行路径:
- 确保引入
spring-boot-starter-actuator依赖 - 在
application.properties中添加配置:
management.endpoints.web.exposure.include=httptrace management.trace.http.enabled=true
- 确保SecurityConfig中已放行
/actuator/**路径(如上述代码所示)
3. 排查响应状态被覆盖的问题
日志中显示响应状态从200变为404,说明有后续过滤器或处理器修改了状态。可以给每个自定义过滤器添加日志,追踪请求流转:
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; System.out.println("进入过滤器[" + this.getClass().getSimpleName() + "],请求路径:" + req.getRequestURI() + ",当前响应状态:" + res.getStatus()); chain.doFilter(request, response); System.out.println("离开过滤器[" + this.getClass().getSimpleName() + "],请求路径:" + req.getRequestURI() + ",最终响应状态:" + res.getStatus()); }
通过日志定位到修改响应状态的环节,针对性调整。
4. 解决EOFException异常
该异常通常是客户端(如Postman)提前关闭连接或响应写入异常导致,确保响应写入完成后调用flush()和close():
response.getWriter().write("登录成功,返回JWT内容"); response.getWriter().flush(); response.getWriter().close();
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

