java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Security AccessDeniedHandler不生效

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

作者:小麟School

本文主要介绍了Spring 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 类就发现起了作用了。

到此这篇关于Spring Security自定义异常 AccessDeniedHandler不生效解决方法的文章就介绍到这了,更多相关Spring Security AccessDeniedHandler不生效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文