CAS框架自定义登录异常提示
- CAS框架自定义登录异常提示
- cas自定义异常
- 自定义异常的步骤-三步走
- 1定义自定义异常类
- 2配置文件配置
- 3逻辑代码中抛出自定义异常
- 总结
- 自定义异常显示失败问题查找
- 自定义异常带msg参数不显示问题处理
- 最后
CAS框架自定义登录异常提示
本地CAS框架异常提示信息走国际化配置文件。CAS框架提供的系统异常比较少,新增多类型的自定义异常(继承系统异常),细化提示。
CAS框架版本5.3.14
cas自定义异常
只是参照别人实现自定义异常提示的步骤,还没有对源码怎么解读。照猫画虎罢了。
此模块包含固定时间内限制登录失败次数提醒(5分钟内,登录失败3次,给出第几次失败,几秒后再重试提醒)
自定义异常的步骤-三步走
1定义自定义异常类
在项目exception文件夹下添加自定义异常类PasswordErrOneException(名字自己随便定义,注意不要和框架中的关键字段重名就好)
类体如下
1继承类(怀疑是固定写法,暂未确认,但这样写能用)及类的内容都是参照别人的代码的。
2serialVersionUID和其他自定义异常类重复也不影响
package com.cas.exception;
import javax.security.auth.login.AccountException;
/**
* 密码错误1一次异常
*
*/
public class PasswordErrOneException extends AccountException {
private static final long serialVersionUID = -3653822412344340111L;
public PasswordErrOneException() {
super();
}
public PasswordErrOneException(String msg) {
super(msg);
}
}
2配置文件配置
application.properties配置文件中添加如下配置自定义异常(应该是固定写法)
1有多个自定义异常用,隔开
2国际化文件配置
cas.authn.exceptions.exceptions=com.cas.exception.PasswordErrOneException,com.cas.exception.PasswordErrFiveException
message_zh_CN.properties中添加
//固定写法为authenticationFailure.自定义异常类名=配置的固定提示,如密码错误一次的中文的unicode码(可搜索在线unicode转码工具)
//本人IDEAunicode码就是显示码,看别人的可以直接显示对应中文,估计是有啥插件吧(猜的)
authenticationFailure.PasswordErrOneException=\u767b\u5f55\u5931\u8d25\u0031\u6b21\u002c\u8fde\u7eed\u767b\u5f55\u5931\u8d25\u0035\u6b21\u002c\u5c06\u88ab\u7981\u7528
3逻辑代码中抛出自定义异常
所在逻辑代码中添加抛出自定义异常
if (!passwordEncoder.matches(password, map.getOrDefault("pwd", StrUtil.EMPTY).toString())) {
//一段时间内连续登录失败N次,给出具体提示
respStr = disableUsername(username,false);
throw new PasswordErrorException("密码错误,"+respStr);
}
/**
* 5分钟内登录失败3次,锁定账号
*
* @param username 用户名
* @param flag 是否--业务逻辑,与锁定逻辑无关,参考可去除
*/
private String disableUsername1(String username,Boolean flag) throws PasswordErrOneException,PasswordErrFiveException {
//是否第一次登录失败,是创建缓存,否数值+1
String cacheKey = "loginfail" + username;
Integer cacheValue = (Integer) redisTemplate.opsForValue().get(cacheKey);
if (ObjectUtil.isEmpty(cacheValue)) {
//用秒比较精确
redisTemplate.opsForValue().set(cacheKey, 1, 3*60, TimeUnit.SECONDS);
return "已登录失败1次,连续登录失败5次,账号将被锁定";
}
//判断数值是否为3,为3直接锁定用户,并且销毁
cacheValue = cacheValue +1;
if(cacheValue >= 5) {
//为3直接禁用用户
if(flag){
//锁定用户
lockUsername(username);
}
//销毁缓存-后续不影响用户解锁后登录
redisTemplate.delete(cacheKey);
return "登录失败5次,账号已被锁定";
}
//为2 3 4 给出操作时间提示和第几次提示 查看剩余时间-https://blog.51cto.com/u_16213339/9207312(redis只更新KEY对应的值,不影响KEY的总过期时间)
//1获取剩余秒数
Long leftTime = redisTemplate.getExpire(cacheKey, TimeUnit.SECONDS);
//2重置登录失败次数-此时KEY对应的过期时间应该为空(暂未核实,纯属猜测)
redisTemplate.opsForValue().set(cacheKey, cacheValue);
//3重新设置过期时间-使用剩余过期时间,以达到KEY总过期时间为3分钟无误
redisTemplate.expire(cacheKey,leftTime, TimeUnit.SECONDS);
return "已登录失败"+cacheValue+"次,连续登录失败5次,账号将被锁定!请于"+leftTime+"秒后再次登录";
}
总结
如上配置好后,代码运行好后,理论上是可以提示国际化文件中配置的中文提示。还不能显示throw new PasswordErrorException(“密码错误,”+respStr);自定义类中传递的MSG参数(后续需要重写源码才行)
自定义异常显示失败问题查找
如上本来是应该至少显示自定义异常对应的国际化配置文件中的文字提示的(密码错误一次)。
但一直显示’认证信息失败‘
后续debug断点打是发现异常扔出还没到读配置文件的时候就报错了,所以实际最后扔出的异常是认证信息失败对应的异常(或UNKNOW类型的异常也是这个中文信息-可配置的-但俺还不会,没太深究)
自定义异常带msg参数不显示问题处理
自定义异常带msg参数不显示,只走固定配置国际化文件中的提示。
要改源码
参照https://blog.csdn.net/qq_43542296/article/details/128933103这个文档改的
1找不到源码位置,找的其他人给我截图的源码位置。找源码位置方法-debug然后下载相关源码。或直接全局导入源码(百度有文,但看不太懂,也没实操,后续看看)
2找到相关源码,创建和源码所在文件夹路径相同的文件夹(源码顶级和项目顶级文件夹同级-项目中是这样,但为啥这样不太懂,是不是一定呀这样也不太懂-应该是固定这样的)
3本地文件夹源码路径下创建同源码类名的类,然后复制源码代码覆盖本地源码类
4只改写需要的本地源码类中方法。其余本地源码类中方法保持不动(不能删)
5本地复制出源码类后,报错的源码代码中如果是未引入导致的,回源码中点看看缺失的文件所在JAR包,找到后,POM中添加引入看看
6其余本地源码类报错,暂时不太会处理,源码逻辑也是不太看的懂,不太找得到目标源码类及方法,后续精进
最后
断点是个好东西
读源码是个好东西,还不太会,后续精进,源码位置都找不到哈哈,debug也找不到目标源码,还好有百度