shiro权限框架,用户登录方法的subject.login(token)会进入自定义的UserNamePasswordRealm类的doGetAuthenticationInfo身份验证方法

通常情况,doGetAuthenticationInfo写法如下:

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
User loginUser = userService.getUserByName(token.getUsername());
if (ObjectUtils.isEmpty(loginUser)) {
throw new UnknownAccountException();
}
if(!loginUser.getPassWord().equals(MD5Util.md5s(String.valueOf(token.getPassword())))){
throw new IncorrectCredentialsException();
}
//其他各种验证
。。。
}

login登录方法:

@ResponseBody
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String doUserLogin(User user, HttpServletRequest request, Model model) {
...
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassWord());
try {
subject.login(token);
} catch (UnknownAccountException uae) { } catch (IncorrectCredentialsException ice) { } catch (LockedAccountException lae) { } catch (ExcessiveAttemptsException eae) { } catch (AuthenticationException ae) { }
...
}

可是最近一次项目,发现通用的方法行不通了,doGetAuthenticationInfo方法抛出的各种异常如UnknownAccountException(包括自定义的异常),外部都无法准确捕捉。

外部login捕捉的异常统一被改写为 AuthenticationException异常(IncorrectCredentialsException等异常的父类),且异常的msg内容也被改写。内容如下:

原因在subject.login(token)的源码里,源码有这么一段:

我们进入doSingleRealmAuthentication方法,可以看见方法里面外抛了UnknownAccountException等异常。

所以如果项目中只定义了一个realm,比如用来进行登录的身份验证,外部是可以正常捕捉的。

但是此次项目我定义了两个realm,一个用来进行登录的身份验证,另一个用来登录后,验证各种请求携带的的token。

我们进入doMultiRealmAuthentication方法,内容如下

再进入afterAllAttempts的实现类,如图5。

发现抛出的异常都被统一改为AuthenticationException异常,且msg也被改写,正如图1所示。

结论

外部无法捕捉doGetAuthenticationInfo方法抛出的异常,原因在于源码,而不是自己的代码有问题。

如果没有改写源码的本事,那么外部想要捕捉各种异常,并在前端显示各种提示语,怎么办?

我的临时解决方法是,doGetAuthenticationInfo只用来验证用户名和密码,

外部直接捕捉AuthenticationException异常,其他的各种验证从doGetAuthenticationInfo方法移至login。

外部无法捕捉Realm的doGetAuthenticationInfo方法抛出的异常的更多相关文章

  1. JUnit 判断方法抛出的异常

    :比方案1更详细,可以进一步判断抛出的异常的报错信息是否符合预期 不用上面那个属性,用 try - catch(因为判断了报错信息,所以不用判断异常的类型了吧) ( 注释:MyAssert类是我自定义 ...

  2. 【Java】ArrayList 的 toArray() 方法抛出 ClassCastException 异常

    第一次用这个方法,结果冒出个莫名其妙的异常来: String[] names = (String[]) mTags.toArray(); 结果会抛出 java.lang.ClassCastExcept ...

  3. Json lib集成stucts2的使用方法 抛出 NestableRuntimeException异常的解决办法

    首先贴出struts 2.3.16需要导入的包 因为使用的是2.3 版本,必须要导入这个包,否则会报java.lang.NoClassDefFoundError: org/apache/commons ...

  4. Effective Java 第三版——74. 文档化每个方法抛出的所有异常

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  5. “全栈2019”Java异常第十一章:重写方法时只能抛出父类异常子集

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  6. 在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出MethodArgumentNotValidException异常,因此,只需要在ExceptionHandler类中添加处理对应异常的方法即可。

    在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出Method ...

  7. 应该抛出什么异常?不应该抛出什么异常?(.NET/C#)

    我在 .NET/C# 建议的异常处理原则 中描述了如何 catch 异常以及重新 throw.然而何时应该 throw 异常,以及应该 throw 什么异常呢? 究竟是谁错了? 代码中从上到下从里到外 ...

  8. Java中主线程如何捕获子线程抛出的异常

    首先明确线程代码的边界.其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界.Runnable接口中run方法原型如下: public void run(); 而所有的具 ...

  9. Response.End抛出ThreadAbortException 异常

    最近在写程序过程中遇到了一个匪夷所思的错误:Response.End()方法抛出了ThreadAbortException异常,我的代码如下: public void doResponse(){ st ...

随机推荐

  1. C++(浅析枚举类型-enum)

    枚举类型 枚举类型(enumeration)是C++中的一种派生数据类型,它是由用户定义的若干枚举常量的集合. 如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型.所谓&quo ...

  2. 理解C++中的头文件和源文件的作用【转】

    一.C++编译模式通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C+ ...

  3. npm安装

    淘宝镜像http://npm.taobao.org/ $ npm install -g cnpm --registry=https://registry.npm.taobao.org mac下 sud ...

  4. 跟着刚哥梳理java知识点——面向对象(八)

    面向对象的核心概念:类和对象. 类:对一类事物描述,是抽象的.概念上的定义. 对象:实际存在的该类事物的每个个体,因而也成为实例(Instance). Java类及类的成员:属性(成员变量Field) ...

  5. python去除文本中的HTML标签

    def SplitHtmlTag(file): with open(file,"r") as f,open("result.txt","w+" ...

  6. Hadoop之HDFS原理及文件上传下载源码分析(上)

    HDFS原理 首先说明下,hadoop的各种搭建方式不再介绍,相信各位玩hadoop的同学随便都能搭出来. 楼主的环境: 操作系统:Ubuntu 15.10 hadoop版本:2.7.3 HA:否(随 ...

  7. NodeJs系列一:神奇的nodejs

    nodejs是什么 nodejs能解决什么问题 非阻塞型I/O及事件环机制 什么时候使用nodejs nodejs是什么 Node.js是让Javascript脱离浏览器运行在服务器的一个平台(或者叫 ...

  8. 基于R树索引的点面关系判断以及效率优化统计

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在之前的博客中,我分别介绍了基于网格的空间索引(http:// ...

  9. 随应潮流-基于ABP+Angulsrjs现代化应用软件开发框架(2)-abp说明

    前言 上周未发布完<基于ABP+Angulsrjs现代化应用软件开发框架(1)-总体介绍> 文章后,好多朋友问了我一些ABP的问题,并且希望我开源我的项目源码,向朋友们说一下,我项目的源码 ...

  10. 如何修改dmesg log buffer size

    CONFIG_LOG_BUF_SHIFT: Kernel log buffer size (16 => 64KB, 17 => 128KB) General informations Th ...