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

Spring Security忽略自定义AuthenticationEntryPoint问题排查求助

问题根源与解决方案

这个问题其实是两个核心点导致的:混淆了Spring Security中认证异常与授权异常的处理组件,再加上Spring Boot 2.1.x版本默认错误处理机制的介入,最终导致403异常被重定向到不存在的/error端点,引发404错误。

核心错误:用错了异常处理组件

你当前配置的authenticationEntryPoint是专门用来处理未认证请求的(比如用户完全没登录就访问受保护资源),而你的场景是用户已认证但权限不足(匹配hasAnyRole规则失败)——这种授权失败的情况,应该用accessDeniedHandler来处理,而非authenticationEntryPoint。

在Spring Security 5.1.x + Spring Boot 2.1.x的组合中,如果未配置accessDeniedHandler,授权失败时会默认转发到Spring Boot的/error端点;如果你没有自定义这个端点,自然就会返回404错误。

修正步骤

1. 实现自定义的AccessDeniedHandler

创建一个处理403授权失败的类,直接返回403响应,避免触发转发逻辑:

public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        // 直接设置403状态码并返回自定义响应(这里用JSON举例,你可以根据需求调整)
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{\"code\": 403, \"message\": \"Insufficient permissions to access this resource\"}");
        // 如果不需要JSON响应,也可以直接调用sendError
        // response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
    }
}

2. 修正Spring Security配置

在你的配置中添加accessDeniedHandler,同时保留authenticationEntryPoint处理未认证场景:

http.exceptionHandling()
    .authenticationEntryPoint(new Http403ForbiddenEntryPoint()) // 处理未认证请求
    .accessDeniedHandler(new CustomAccessDeniedHandler()) // 处理授权失败(403)场景
    .and()
    .addFilter(headerAuthenticationFilter)
    .httpBasic().disable()
    .csrf().disable()
    .authenticationProvider(preAuthenticatedAuthenticationProvider)
    .authorizeRequests()
    .antMatchers("/api/**")
    .hasAnyRole("ROLE1", "ROLE2")
    .and()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

3. 可选:调整Spring Boot错误配置(避免意外重定向)

为了彻底防止Spring Boot默认错误机制介入,可以在application.properties或application.yml中添加以下配置:

# 关闭白标错误页,避免默认的错误页面干扰
server.error.whitelabel.enabled=false

额外检查点

确认你的Http403ForbiddenEntryPoint实现是正确的——它应该直接返回403响应,而非触发重定向,比如:

public class Http403ForbiddenEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authentication required");
    }
}

如果这个类里包含重定向逻辑,也会导致类似的异常跳转问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:57:45