Security 自定义异常 AccessDeniedHandler不生效解决

【出现场景】

最近在项目中通过Security实现单点登录的时候,发现明明应该触发 AccessDeniedException 异常,但没有报出来,应该是报了GlobalException里面定义的全局异常,发现是被全局异常捕获了。项目还原成本有点大 我就先把大体解决流程记录一下。

【解决思路】

既然发现是被全局异常捕获掉了,我们就把思路放到 如何让异常不被全局异常捕获,而自己定义异常 进行错误消息的配置呢?

首先新增一个类

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    private static final ObjectMapper objectMapper=new ObjectMapper();
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse  httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        //在这里返回一个包含着错误信息的对象数据
        JsonResult jsonResult=JsonResult.fail(ServiceCode.ERR_FORBIDDEN, "您无此权限!");
        httpServletResponse.setContentType("application/json;charset=utf-8");
        httpServletResponse.getWriter().write(objectMapper.writeValueAsString(jsonResult));
        httpServletResponse.flushBuffer();
    }
}

通过实现AccessDeniedHandler 接口 重写的handle 方法进行捕获,AcceseDeniedException异常.

至此 可能就算解决完了?

可能一般项目中 这样解决就可以了,但是我发现配置后并没有生效 ,还是会被Global里的最高Exception捕获。

【再次解析】

因为我们是分布式的项目。查阅一些资料后 在实现单点登录的项目中新增了如下类

@ControllerAdvice
public class AccessDeniedExceptionHandler {
    @ExceptionHandler(AccessDeniedException.class)
    public void accessDeniedException(AccessDeniedException e) throws AccessDeniedException{
        throw e;
    }
}

首先 说 @ControllerAdvice注解

@ControllerAdvice 本质也是一个@Component,所以配置上这个注解 也会被当成组件扫描

简要说明一下该注解的意思。简单来说 他就是一个拦截类,在@ExcepitonHandler 或 @ModelAttribute注解修饰的)方法的类而提供的专业化的Component, 以供多个Controller类所共享。简单来理解 就是AOP的思想的注解实现,咱们通过@ExceptionHandler注解 配置好规则,ControllerAdvice就会帮咱们进行拦截。

默认情况下 如果@ControllerAdvice什么都不写 就是拦截所有controller 。如果想指定包拦截 可以这样写  @ControllerAdvice(basePackages = "com.xxx.controller")进行指定包的拦截。

接下来看@ExceptionHandler注解

简单来说 就是对指定的异常 进行处理。

@ExceptionHandler 注解 是要和 @ControllerAdvice 注解搭配到一起用的。

 可以看到 ExceptionHandler里面的参数 只有一个Throwable ,这也就是说他可以接收任何Throwable类型的异常。 使用方法如我上面所示这样 @ExceptionHandler(AccessDeniedException.class)进行配置即可

 这样就是进行 AccessDeniedException 异常的拦截。

说回正文,在我的项目中添加完@ControllerAdvice注解的这个类后,报异常时就不会再走 GlobalException 全局配置的异常了,深层次的原因我没有深挖,我觉得应该是本项目中配置的@ControllerAdvice注解要晚于Global的包@ControllerAdvice的加载时间吧。

配置完这个类后,第一个MyAccessDeniedHandler 类就发现起了作用了。

如果有问题可以留言指正 讨论。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值