fix:AsyncFactory类中的recordLogininfor方法抛出的NPE
原因:在前端调用退出登录的时候(/logout),SpringSecurity会回调LogoutSuccessHandlerImpl实现类中的onLogoutSuccess方法做一些清理工作,包括记录登录日志。 记录登录日志调用的是AsyncFactory类中的recordLogininfor方法,在此方法中使用ServletUtils.getRequest()方法获取HttpServletRequest 对象。但onLogoutSuccess方法是被【异步】调用的,从而导致ServletUtils.getRequest()返回的一直是null。 证明:虽然因时间原因没具体看SpringSecurity源码,但可以用一个小实验证明。 在JwtAuthenticationTokenFilter类中的doFilterInternal增加一行打印当前线程id的日志;然后 在LogoutSuccessHandlerImpl类中的onLogoutSuccess也相应增加一行打印当前线程id的日志。 最后查看日志发现两个线程id不一致,从而证明onLogoutSuccess方法别【异步】调用。 修复:因为考虑到最好不破坏原API,所以使用ThreadLocal解决该问题。
This commit is contained in:
parent
bbbe83b737
commit
b044503346
@ -16,6 +16,8 @@ import com.ruoyi.system.service.ISysLogininforService;
|
||||
import com.ruoyi.system.service.ISysOperLogService;
|
||||
import eu.bitwalker.useragentutils.UserAgent;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 异步工厂(产生任务用)
|
||||
*
|
||||
@ -24,6 +26,7 @@ import eu.bitwalker.useragentutils.UserAgent;
|
||||
public class AsyncFactory
|
||||
{
|
||||
private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
|
||||
public static final ThreadLocal<HttpServletRequest> REQUEST_THREAD_LOCAL = ThreadLocal.withInitial(ServletUtils::getRequest);
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
@ -37,8 +40,14 @@ public class AsyncFactory
|
||||
public static TimerTask recordLogininfor(final String username, final String status, final String message,
|
||||
final Object... args)
|
||||
{
|
||||
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
|
||||
final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
|
||||
final HttpServletRequest request = REQUEST_THREAD_LOCAL.get();
|
||||
|
||||
final String header = request.getHeader("User-Agent");
|
||||
final UserAgent userAgent = UserAgent.parseUserAgentString(header);
|
||||
final String ip = IpUtils.getIpAddr(request);
|
||||
|
||||
REQUEST_THREAD_LOCAL.remove();
|
||||
|
||||
return new TimerTask()
|
||||
{
|
||||
@Override
|
||||
|
@ -46,6 +46,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
|
||||
// 删除用户缓存记录
|
||||
tokenService.delLoginUser(loginUser.getToken());
|
||||
// 记录用户退出日志
|
||||
AsyncFactory.REQUEST_THREAD_LOCAL.set(request);
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
|
||||
}
|
||||
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
|
||||
|
Loading…
x
Reference in New Issue
Block a user