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

Spring Security中AuthenticationEntryPoint与@ControllerAdvice共存问题咨询

问题原因

@ControllerAdvice默认会捕获所有Spring容器中抛出的Exception类型异常,而Spring Security的认证相关异常(AuthenticationException、AccessDeniedException等)是在请求到达Controller之前的过滤器链阶段抛出的,你当前配置的全局异常处理器捕获了所有Exception,会覆盖掉AuthenticationEntryPoint的处理逻辑。

解决方案

你可以任选以下任意一种方式实现两者共存:

方案1:全局异常处理器排除Security相关异常

修改你的ExceptionControllerAdvice,在处理全局异常前判断异常类型,如果是Spring Security相关的认证/鉴权异常,直接抛出,交给AuthenticationEntryPoint处理即可,代码示例:

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.access.AccessDeniedException;

@ControllerAdvice
public class ExceptionControllerAdvice   {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionControllerAdvice.class);

    /****    500   Entity  */
    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public final ErrorDetail handleAllExceptions(Exception ex) throws Exception {
        // 排除Spring Security认证、鉴权异常,交给Security的异常处理器处理
        if (ex instanceof AuthenticationException || ex instanceof AccessDeniedException) {
            throw ex;
        }
        LOGGER.error("An unexpected error occurred", ex);

        ErrorDetail problem = new ErrorDetail("Internal Error",
                "An unexpected error has occurred");
        problem.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());

        return problem;
    }
}

方案2:限定全局异常处理器仅处理Controller层异常

你可以给@ControllerAdvice指定作用范围,仅处理业务Controller抛出的异常,过滤器层的异常不会被捕获,自然会走Security的EntryPoint逻辑,示例:

// 仅捕获加了@RestController、@Controller注解的类抛出的异常
@ControllerAdvice(annotations = {RestController.class, Controller.class})
public class ExceptionControllerAdvice   {
    // 原有逻辑保持不变
}

两种方案都不需要修改原有Security配置和EntryPoint逻辑,可直接兼容现有功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 04:15:04