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

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端点默认禁用,需手动开启并放行路径:

  1. 确保引入spring-boot-starter-actuator依赖
  2. 在application.properties中添加配置:
management.endpoints.web.exposure.include=httptrace
management.trace.http.enabled=true
  1. 确保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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 08:07:30