记录一下若依集成aj-captcha实现滑块验证码的一个巨大的坑。
用的是若依前后端分离版3.8.4。
集成过程直接用官方给的文档。这里的报错是原封不动的按照官方给的文档集成插件出现的问题。以下提供的报错分析代码需集成后才能看懂。
集成aj-captcha实现滑块验证码
验证码可以用,就是没法登录了,登录报错
直接上错误代码:
com.xxxx.common.exception.ServiceException: null
at com.xxxx.framework.web.service.SysLoginService.login(SysLoginService.java:250)
at com.xxxx.web.controller.system.SysLoginController.login(SysLoginController.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
报错就说是空指针异常。分析错误原因
throw new ServiceException(e.getMessage());
这里报空指针异常,说明是e.getMessage()为null了,然后new一个ServiceException是不能为空的,所以就报空指针。这里真的很奇怪。
又分析了半天,追踪到是这个类的
com.xxxx.framework.web.service.SysPasswordService
如下代码:
public void validate(SysUser user)
{
Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
String username = usernamePasswordAuthenticationToken.getName();
String password = usernamePasswordAuthenticationToken.getCredentials().toString();
Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
usernamePasswordAuthenticationToken为空null了。
分析了半天,最后才找到原因,是若依的官方代码出了问题我真的要吐血了。
解决方案
类名:
com.xxxx.framework.web.service.SysLoginService
官方代码:
// 用户验证
Authentication authentication = null;
try
{
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
}
应该正确修改后的代码:
// 用户验证
Authentication authentication = null;
try
{
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
AuthenticationContextHolder.setContext(authenticationToken);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(authenticationToken);
}
搞了半天没有给Context赋值,所以Security拿当前登录用户的对象就为空了。
延伸
记录了一下这个坑,希望大家集成这个滑动验证码插件的时候可以提前避免这个问题。
贴一下异常为空的优化代码
if(StringUtils.isBlank(e.getMessage())) {
throw new ServiceException("未知错误");
}
else {
throw new ServiceException(e.getMessage());
}
这样就算为空也不会乱报错了。