记录一下若依集成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());
                }

这样就算为空也不会乱报错了。

Logo

快速构建 Web 应用程序

更多推荐