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

Spring Security调用不存在端点返回403而非404如何解决?

问题原因

Spring Security的过滤器执行优先级远高于Spring MVC的请求映射匹配逻辑。你当前配置的anyRequest().authenticated()会对所有进入容器的请求先做权限校验,只要用户未登录/无权限,直接返回403,请求根本不会走到Spring MVC层去判断端点是否存在,所以不会触发404。


方案1:显式声明需要保护的路径范围,不使用anyRequest()匹配所有路径

如果项目路径规范,所有需要保护的接口都有统一前缀,推荐用这个方案,实现最简单:只对明确的业务路径前缀做权限校验,未匹配到的路径直接放通,走Spring MVC正常的404逻辑即可。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().and().cors().disable();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    http.authorizeRequests()
        // 公开接口放行
        .antMatchers("/login", "/api/v1/auth/**").permitAll()
        // 只对业务接口路径做认证要求,可根据实际业务前缀调整
        .antMatchers("/api/v1/**").authenticated();
    // 移除anyRequest().authenticated()配置,其余路径直接放通走MVC逻辑
}

方案2:自定义异常处理器,无权限时先判断端点是否存在

如果项目路径分散,没办法用前缀统一匹配,可以自定义认证入口和权限拒绝处理器,在返回异常前先判断请求路径是否存在对应的端点。

  1. 首先自定义两个异常处理器:
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Autowired
    private HandlerMapping handlerMapping;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        try {
            // 检查是否存在对应的请求映射
            handlerMapping.getHandler(request);
            // 存在对应端点,返回401未认证
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
        } catch (NoHandlerFoundException e) {
            // 不存在对应端点,返回404
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "资源不存在");
        }
    }
}
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    @Autowired
    private HandlerMapping handlerMapping;

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        try {
            handlerMapping.getHandler(request);
            response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
        } catch (NoHandlerFoundException e) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "资源不存在");
        }
    }
}
  1. 在Spring MVC配置中开启找不到处理器时抛异常的开关:
# application.yml配置
spring:
  mvc:
    throw-exception-if-no-handler-found: true
  web:
    resources:
      add-mappings: false # 若后端需要托管静态资源可删除此配置,按需调整匹配规则即可
  1. 把自定义处理器配置到Spring Security规则中:
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().and().cors().disable();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    http.authorizeRequests()
        .antMatchers("/login", "/api/v1/auth/**").permitAll()
        .anyRequest().authenticated();
    // 注册自定义异常处理器
    http.exceptionHandling()
        .authenticationEntryPoint(customAuthenticationEntryPoint)
        .accessDeniedHandler(customAccessDeniedHandler);
}

内容的提问来源于stack exchange,提问作者Avaldor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:06:03