当前位置:   article > 正文

SpringSecurity的loadUserByUsername抛出异常无法捕获原因分析

loaduserbyusername

SpringSecurity的loadUserByUsername抛出异常无法捕获原因分析


SpringSecurity 相信大家对它都不陌生,这是一个令我又爱又恨的框架,配置不简单,但是功能却异常强大。下面我们就一起来分析一下loadUserByUsername 里抛出自定义异常无法捕获的原因吧

嗯,话不多说,自定义异常,全局异常处理拦截器、Security配置等我就不说了,直接上重点吧!

1、分析原因

首先我们在 loadUserByUsername 里抛出一个异常 ,为了演示,我直接在loadUserByUsername里抛出异常了

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      if (true){
          throw new BusinessException(ResultCodeEnum.FAIL);
      }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用 postman 请求login接口

到后台查看,我抛出的异常直接被打印了,并没有被全局异常拦截器捕获,并且异常类也不是我抛出的,接下来我们debug查看

debug测试,好家伙,我终于找到了原因,原来在 DaoAuthenticationProvider 里就给我捕获了,还给我换成了其他的异常,可是明明是捕获了,为什么会打印了,继续查看

原来在doFilter里捕获并且打印了

2、解决方式

好了,原因我们找到了,那么怎么解决呢?我想到了两种方法

2.1、方式一

第一种,前后端分离模式,在登入失败的handler里处理,如下。

1、我们其实可以在security失败的handler里取得InternalAuthenticationServiceException异常,查看源码可以发现它是AuthenticationException异常的子类

2、刚刚查看源码其实我们就发现抛出 InternalAuthenticationServiceException 异常,并没有改变我们抛出的异常,而是把我们抛出的异常传递给它了,所以我们只需要取出来(ex)就好了

@Override
public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response,
                                        AuthenticationException e) throws IOException, ServletException {
   ErrorResult result = null;
   //抛出的异常

   if (e instanceof InternalAuthenticationServiceException){
      InternalAuthenticationServiceException exception = (InternalAuthenticationServiceException) e;
      if (exception.getCause()!=null) {
         //判断抛出的是否是自己定义的异常
         if (exception.getCause() instanceof BusinessException){
             //自定义异常
            BusinessException businessException= (BusinessException) exception.getCause();
            result = ErrorResult.failure(businessException,request, HttpStatus.OK);
          }else {
             //用户不存在
             result=ErrorResult.failure(ResultCodeEnum.USER_ACCOUNT_NOT_EXIST,request,HttpStatus.OK);
          }
        }else {
           // 返回用户不存在
         result = ErrorResult.failure(ResultCodeEnum.USER_ACCOUNT_NOT_EXIST,request,HttpStatus.OK);
      }
    }

    response.setContentType("text/json;charset=utf-8");
    response.getWriter().write(JSONObject.toJSONString(result));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
2.2、方式二

第二种,其实我们也可以写一个全局异常拦截器,捕获InternalAuthenticationServiceException 异常来处理它,但是不建议这么做,所以我不细写了,哈哈哈。

@ExceptionHandler(InternalAuthenticationServiceException.class)
@ResponseBody
public ErrorResult handleBusinessException(BusinessException e, HttpServletRequest request){
       //一些列操作....
}
  • 1
  • 2
  • 3
  • 4
  • 5

InternalAuthenticationServiceException 是用户不存在异常,请正确使用!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/481603
推荐阅读
  

闽ICP备14008679号