master
RuoYi 6 years ago committed by Limy
parent 70b1c54ddc
commit 0605d509cc

@ -1,69 +0,0 @@
package com.ruoyi.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.project.monitor.logininfor.domain.Logininfor;
import com.ruoyi.project.monitor.logininfor.service.LogininforServiceImpl;
import eu.bitwalker.useragentutils.UserAgent;
/**
*
*
* @author ruoyi
*/
@Deprecated // 加入异步功能之后,该类已无意义
public class SystemLogUtils {
private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
/**
* [ip][][][]
* <p/>
* loginError loginSuccess passwordError
* changePassword changeStatus
*
* @param username
* @param op
* @param msg
* @param args
*/
public static void log(String username, String status, String msg, Object... args) {
StringBuilder s = new StringBuilder();
s.append(LogUtils.getBlock(ShiroUtils.getIp()));
s.append(AddressUtils.getRealAddressByIP(ShiroUtils.getIp()));
s.append(LogUtils.getBlock(username));
s.append(LogUtils.getBlock(status));
s.append(LogUtils.getBlock(msg));
sys_user_logger.info(s.toString(), args);
if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) {
saveOpLog(username, msg, Constants.SUCCESS);
} else if (Constants.LOGIN_FAIL.equals(status)) {
saveOpLog(username, msg, Constants.FAIL);
}
}
public static void saveOpLog(String username, String message, String status) {
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
// 获取客户端操作系统
String os = userAgent.getOperatingSystem().getName();
// 获取客户端浏览器
String browser = userAgent.getBrowser().getName();
LogininforServiceImpl logininforService = SpringUtils.getBean(LogininforServiceImpl.class);
Logininfor logininfor = new Logininfor();
logininfor.setLoginName(username);
logininfor.setStatus(status);
logininfor.setIpaddr(ShiroUtils.getIp());
logininfor.setLoginLocation(AddressUtils.getRealAddressByIP(ShiroUtils.getIp()));
logininfor.setBrowser(browser);
logininfor.setOs(os);
logininfor.setMsg(message);
logininforService.insertLogininfor(logininfor);
}
}

@ -2,7 +2,6 @@ package com.ruoyi.framework.aspectj;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature; import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterReturning;
@ -15,7 +14,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -35,128 +33,144 @@ import com.ruoyi.project.system.user.domain.User;
@Aspect @Aspect
@Component @Component
@EnableAsync @EnableAsync
public class LogAspect { public class LogAspect
private static final Logger log = LoggerFactory.getLogger(LogAspect.class); {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
// 配置织入点
@Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.Log)") // 配置织入点
public void logPointCut() { @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.Log)")
} public void logPointCut()
{
/** }
*
* /**
* @param joinPoint *
* *
*/ * @param joinPoint
@AfterReturning(pointcut = "logPointCut()") */
public void doBefore(JoinPoint joinPoint) { @AfterReturning(pointcut = "logPointCut()")
handleLog(joinPoint, null); public void doBefore(JoinPoint joinPoint)
} {
handleLog(joinPoint, null);
/** }
*
* /**
* @param joinPoint *
* @param e *
*/ * @param joinPoint
@AfterThrowing(value = "logPointCut()", throwing = "e") * @param e
public void doAfter(JoinPoint joinPoint, Exception e) { */
handleLog(joinPoint, e); @AfterThrowing(value = "logPointCut()", throwing = "e")
} public void doAfter(JoinPoint joinPoint, Exception e)
{
@Async handleLog(joinPoint, e);
protected void handleLog(final JoinPoint joinPoint, final Exception e) { }
try {
// 获得注解 @Async
Log controllerLog = getAnnotationLog(joinPoint); protected void handleLog(final JoinPoint joinPoint, final Exception e)
if (controllerLog == null) { {
return; try
} {
// 获得注解
// 获取当前的用户 Log controllerLog = getAnnotationLog(joinPoint);
User currentUser = ShiroUtils.getUser(); if (controllerLog == null)
{
// *========数据库日志=========*// return;
OperLog operLog = new OperLog(); }
operLog.setStatus(BusinessStatus.SUCCESS);
// 请求的地址 // 获取当前的用户
String ip = ShiroUtils.getIp(); User currentUser = ShiroUtils.getUser();
operLog.setOperIp(ip);
// *========数据库日志=========*//
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); OperLog operLog = new OperLog();
if (currentUser != null) { operLog.setStatus(BusinessStatus.SUCCESS);
operLog.setOperName(currentUser.getLoginName()); // 请求的地址
if (StringUtils.isNotNull(currentUser.getDept()) && StringUtils.isNotEmpty(currentUser.getDept().getDeptName())) { String ip = ShiroUtils.getIp();
operLog.setDeptName(currentUser.getDept().getDeptName()); operLog.setOperIp(ip);
}
} operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
if (currentUser != null)
if (e != null) { {
operLog.setStatus(BusinessStatus.FAIL); operLog.setOperName(currentUser.getLoginName());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); if (StringUtils.isNotNull(currentUser.getDept())
} && StringUtils.isNotEmpty(currentUser.getDept().getDeptName()))
// 设置方法名称 {
String className = joinPoint.getTarget().getClass().getName(); operLog.setDeptName(currentUser.getDept().getDeptName());
String methodName = joinPoint.getSignature().getName(); }
operLog.setMethod(className + "." + methodName + "()"); }
// 处理设置注解上的参数
getControllerMethodDescription(controllerLog, operLog); if (e != null)
// 保存数据库 {
AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); operLog.setStatus(BusinessStatus.FAIL);
} catch (Exception exp) { operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
// 记录本地异常日志 }
log.error("==前置通知异常=="); // 设置方法名称
log.error("异常信息:{}", exp.getMessage()); String className = joinPoint.getTarget().getClass().getName();
exp.printStackTrace(); String methodName = joinPoint.getSignature().getName();
} operLog.setMethod(className + "." + methodName + "()");
} // 处理设置注解上的参数
getControllerMethodDescription(controllerLog, operLog);
/** // 保存数据库
* Controller AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
* }
* @param joinPoint catch (Exception exp)
* {
* @return // 记录本地异常日志
* @throws Exception log.error("==前置通知异常==");
*/ log.error("异常信息:{}", exp.getMessage());
public void getControllerMethodDescription(Log log, OperLog operLog) throws Exception { exp.printStackTrace();
// 设置action动作 }
operLog.setAction(log.action()); }
// 设置标题
operLog.setTitle(log.title()); /**
// 设置channel * Controller
operLog.setChannel(log.channel()); *
// 是否需要保存request参数和值 * @param joinPoint
if (log.isSaveRequestData()) { * @return
// 获取参数的信息,传入到数据库中。 * @throws Exception
setRequestValue(operLog); */
} public void getControllerMethodDescription(Log log, OperLog operLog) throws Exception
} {
// 设置action动作
/** operLog.setAction(log.action());
* log // 设置标题
* operLog.setTitle(log.title());
* @param operLog // 设置channel
* @param request operLog.setChannel(log.channel());
*/ // 是否需要保存request参数和值
private void setRequestValue(OperLog operLog) { if (log.isSaveRequestData())
Map<String, String[]> map = ServletUtils.getRequest().getParameterMap(); {
String params = JSONObject.toJSONString(map); // 获取参数的信息,传入到数据库中。
operLog.setOperParam(StringUtils.substring(params, 0, 255)); setRequestValue(operLog);
} }
}
/**
* /**
*/ * log
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception { *
Signature signature = joinPoint.getSignature(); * @param operLog
MethodSignature methodSignature = (MethodSignature) signature; * @param request
Method method = methodSignature.getMethod(); */
private void setRequestValue(OperLog operLog)
if (method != null) { {
return method.getAnnotation(Log.class); Map<String, String[]> map = ServletUtils.getRequest().getParameterMap();
} String params = JSONObject.toJSONString(map);
return null; operLog.setOperParam(StringUtils.substring(params, 0, 255));
} }
/**
*
*/
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception
{
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null)
{
return method.getAnnotation(Log.class);
}
return null;
}
} }

@ -9,18 +9,35 @@ import java.util.concurrent.TimeUnit;
* *
* @author liuhulu * @author liuhulu
*/ */
public class AsyncManager { public class AsyncManager
// 操作延迟 {
private final int OPERATE_DELAY_TIME = 10; /**
// 异步操作此案城池 * 10
private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5); */
// 单例 private final int OPERATE_DELAY_TIME = 10;
private static AsyncManager me = new AsyncManager();
public static AsyncManager me() { /**
return me; * 线
} */
// 执行任务 private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5);
public void execute(TimerTask task) {
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); /**
} *
*/
private static AsyncManager me = new AsyncManager();
public static AsyncManager me()
{
return me;
}
/**
*
*
* @param task
*/
public void execute(TimerTask task)
{
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
} }

@ -1,10 +1,8 @@
package com.ruoyi.framework.manager.factory; package com.ruoyi.framework.manager.factory;
import java.util.TimerTask; import java.util.TimerTask;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.AddressUtils; import com.ruoyi.common.utils.AddressUtils;
import com.ruoyi.common.utils.LogUtils; import com.ruoyi.common.utils.LogUtils;
@ -18,7 +16,6 @@ import com.ruoyi.project.monitor.online.domain.UserOnline;
import com.ruoyi.project.monitor.online.service.IUserOnlineService; import com.ruoyi.project.monitor.online.service.IUserOnlineService;
import com.ruoyi.project.monitor.operlog.domain.OperLog; import com.ruoyi.project.monitor.operlog.domain.OperLog;
import com.ruoyi.project.monitor.operlog.service.IOperLogService; import com.ruoyi.project.monitor.operlog.service.IOperLogService;
import eu.bitwalker.useragentutils.UserAgent; import eu.bitwalker.useragentutils.UserAgent;
/** /**
@ -27,99 +24,111 @@ import eu.bitwalker.useragentutils.UserAgent;
* @author liuhulu * @author liuhulu
* *
*/ */
public class AsyncFactory { public class AsyncFactory
private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user"); {
private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
/** /**
* session * session
* *
* @param operLog * @param session 线
* @return * @return task
*/ */
public static TimerTask syncSessionToDb(final OnlineSession session) { public static TimerTask syncSessionToDb(final OnlineSession session)
return new TimerTask() { {
@Override return new TimerTask()
public void run() { {
UserOnline online = new UserOnline(); @Override
online.setSessionId(String.valueOf(session.getId())); public void run()
online.setDeptName(session.getDeptName()); {
online.setLoginName(session.getLoginName()); UserOnline online = new UserOnline();
online.setStartTimestamp(session.getStartTimestamp()); online.setSessionId(String.valueOf(session.getId()));
online.setLastAccessTime(session.getLastAccessTime()); online.setDeptName(session.getDeptName());
online.setExpireTime(session.getTimeout()); online.setLoginName(session.getLoginName());
online.setIpaddr(session.getHost()); online.setStartTimestamp(session.getStartTimestamp());
online.setLonginLocation(AddressUtils.getRealAddressByIP(session.getHost())); online.setLastAccessTime(session.getLastAccessTime());
online.setBrowser(session.getBrowser()); online.setExpireTime(session.getTimeout());
online.setOs(session.getOs()); online.setIpaddr(session.getHost());
online.setStatus(session.getStatus()); online.setLonginLocation(AddressUtils.getRealAddressByIP(session.getHost()));
online.setSession(session); online.setBrowser(session.getBrowser());
SpringUtils.getBean(IUserOnlineService.class).saveOnline(online); online.setOs(session.getOs());
online.setStatus(session.getStatus());
online.setSession(session);
SpringUtils.getBean(IUserOnlineService.class).saveOnline(online);
} }
}; };
} }
/**
* log
*
* @param rc
* @return
*/
public static TimerTask recordOper(final OperLog operLog) {
return new TimerTask() {
@Override
public void run() {
// 远程查询操作地点
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
SpringUtils.getBean(IOperLogService.class).insertOperlog(operLog);
}
};
}
/** /**
* *
* *
* @param username * @param operLog
* @param status * @return task
* @param message */
* @param userAgent public static TimerTask recordOper(final OperLog operLog)
* @param args {
* @return return new TimerTask()
*/ {
public static TimerTask recordLogininfor(final String username, final String status, final String message, final Object... args) { @Override
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); public void run()
return new TimerTask() { {
@Override // 远程查询操作地点
public void run() { operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
StringBuilder s = new StringBuilder(); SpringUtils.getBean(IOperLogService.class).insertOperlog(operLog);
s.append(LogUtils.getBlock(ShiroUtils.getIp())); }
s.append(AddressUtils.getRealAddressByIP(ShiroUtils.getIp())); };
s.append(LogUtils.getBlock(username)); }
s.append(LogUtils.getBlock(status));
s.append(LogUtils.getBlock(message));
// 打印信息到日志
sys_user_logger.info(s.toString(), args);
// 获取客户端操作系统
String os = userAgent.getOperatingSystem().getName();
// 获取客户端浏览器
String browser = userAgent.getBrowser().getName();
// 封装对象
Logininfor logininfor = new Logininfor();
logininfor.setLoginName(username);
logininfor.setIpaddr(ShiroUtils.getIp());
logininfor.setLoginLocation(AddressUtils.getRealAddressByIP(ShiroUtils.getIp()));
logininfor.setBrowser(browser);
logininfor.setOs(os);
logininfor.setMsg(message);
// 日志状态
if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) {
logininfor.setStatus(Constants.SUCCESS);
} else if (Constants.LOGIN_FAIL.equals(status)) {
logininfor.setStatus(Constants.FAIL);
}
// 插入数据
SpringUtils.getBean(LogininforServiceImpl.class).insertLogininfor(logininfor);
}
};
}
/**
*
*
* @param username
* @param status
* @param message
* @param args
* @return task
*/
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"));
return new TimerTask()
{
@Override
public void run()
{
StringBuilder s = new StringBuilder();
s.append(LogUtils.getBlock(ShiroUtils.getIp()));
s.append(AddressUtils.getRealAddressByIP(ShiroUtils.getIp()));
s.append(LogUtils.getBlock(username));
s.append(LogUtils.getBlock(status));
s.append(LogUtils.getBlock(message));
// 打印信息到日志
sys_user_logger.info(s.toString(), args);
// 获取客户端操作系统
String os = userAgent.getOperatingSystem().getName();
// 获取客户端浏览器
String browser = userAgent.getBrowser().getName();
// 封装对象
Logininfor logininfor = new Logininfor();
logininfor.setLoginName(username);
logininfor.setIpaddr(ShiroUtils.getIp());
logininfor.setLoginLocation(AddressUtils.getRealAddressByIP(ShiroUtils.getIp()));
logininfor.setBrowser(browser);
logininfor.setOs(os);
logininfor.setMsg(message);
// 日志状态
if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
{
logininfor.setStatus(Constants.SUCCESS);
}
else if (Constants.LOGIN_FAIL.equals(status))
{
logininfor.setStatus(Constants.FAIL);
}
// 插入数据
SpringUtils.getBean(LogininforServiceImpl.class).insertLogininfor(logininfor);
}
};
}
} }

@ -3,7 +3,6 @@ package com.ruoyi.framework.shiro.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ShiroConstants; import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
@ -27,101 +26,104 @@ import com.ruoyi.project.system.user.service.IUserService;
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class LoginService { public class LoginService
@Autowired {
private PasswordService passwordService; @Autowired
private PasswordService passwordService;
@Autowired
private IUserService userService; @Autowired
private IUserService userService;
/**
* /**
*/ *
public User login(String username, String password) { */
// 验证码校验 public User login(String username, String password)
if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA))) { {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); // 验证码校验
// SystemLogUtils.log(username, Constants.LOGIN_FAIL, if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
// MessageUtils.message("user.jcaptcha.error")); {
throw new CaptchaException(); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
} throw new CaptchaException();
// 用户名或密码为空 错误 }
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { // 用户名或密码为空 错误
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
// SystemLogUtils.log(username, Constants.LOGIN_FAIL, {
// MessageUtils.message("not.null")); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
throw new UserNotExistsException(); throw new UserNotExistsException();
} }
// 密码如果不在指定范围内 错误 // 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH || password.length() > UserConstants.PASSWORD_MAX_LENGTH) { if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
// SystemLogUtils.log(username, Constants.LOGIN_FAIL, {
// MessageUtils.message("user.password.not.match")); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException(); throw new UserPasswordNotMatchException();
} }
// 用户名不在指定范围内 错误 // 用户名不在指定范围内 错误
if (username.length() < UserConstants.USERNAME_MIN_LENGTH || username.length() > UserConstants.USERNAME_MAX_LENGTH) { if (username.length() < UserConstants.USERNAME_MIN_LENGTH
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); || username.length() > UserConstants.USERNAME_MAX_LENGTH)
// SystemLogUtils.log(username, Constants.LOGIN_FAIL, {
// MessageUtils.message("user.password.not.match")); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException(); throw new UserPasswordNotMatchException();
} }
// 查询用户信息 // 查询用户信息
User user = userService.selectUserByLoginName(username); User user = userService.selectUserByLoginName(username);
if (user == null && maybeMobilePhoneNumber(username)) { if (user == null && maybeMobilePhoneNumber(username))
user = userService.selectUserByPhoneNumber(username); {
} user = userService.selectUserByPhoneNumber(username);
}
if (user == null && maybeEmail(username)) {
user = userService.selectUserByEmail(username); if (user == null && maybeEmail(username))
} {
user = userService.selectUserByEmail(username);
if (user == null || UserStatus.DELETED.getCode().equals(user.getDelFlag())) { }
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
// SystemLogUtils.log(username, Constants.LOGIN_FAIL, if (user == null || UserStatus.DELETED.getCode().equals(user.getDelFlag()))
// MessageUtils.message("user.not.exists")); {
throw new UserNotExistsException(); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
} throw new UserNotExistsException();
}
passwordService.validate(user, password);
passwordService.validate(user, password);
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark()))); if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
// SystemLogUtils.log(username, Constants.LOGIN_FAIL, {
// MessageUtils.message("user.blocked", user.getRemark())); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
throw new UserBlockedException(user.getRemark()); throw new UserBlockedException(user.getRemark());
} }
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
// SystemLogUtils.log(username, Constants.LOGIN_SUCCESS, recordLoginInfo(user);
// MessageUtils.message("user.login.success")); return user;
recordLoginInfo(user); }
return user;
} private boolean maybeEmail(String username)
{
private boolean maybeEmail(String username) { if (!username.matches(UserConstants.EMAIL_PATTERN))
if (!username.matches(UserConstants.EMAIL_PATTERN)) { {
return false; return false;
} }
return true; return true;
} }
private boolean maybeMobilePhoneNumber(String username) { private boolean maybeMobilePhoneNumber(String username)
if (!username.matches(UserConstants.MOBILE_PHONE_NUMBER_PATTERN)) { {
return false; if (!username.matches(UserConstants.MOBILE_PHONE_NUMBER_PATTERN))
} {
return true; return false;
} }
return true;
/** }
*
*/ /**
public void recordLoginInfo(User user) { *
user.setLoginIp(ShiroUtils.getIp()); */
user.setLoginDate(DateUtils.getNowDate()); public void recordLoginInfo(User user)
userService.updateUserInfo(user); {
} user.setLoginIp(ShiroUtils.getIp());
user.setLoginDate(DateUtils.getNowDate());
userService.updateUserInfo(user);
}
} }

@ -1,16 +1,13 @@
package com.ruoyi.framework.shiro.service; package com.ruoyi.framework.shiro.service;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager; import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.crypto.hash.Md5Hash; import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException; import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
@ -25,66 +22,70 @@ import com.ruoyi.project.system.user.domain.User;
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class PasswordService { public class PasswordService
{
@Autowired
private CacheManager cacheManager; @Autowired
private CacheManager cacheManager;
private Cache<String, AtomicInteger> loginRecordCache;
private Cache<String, AtomicInteger> loginRecordCache;
@Value(value = "${user.password.maxRetryCount}")
private String maxRetryCount; @Value(value = "${user.password.maxRetryCount}")
private String maxRetryCount;
@PostConstruct
public void init() { @PostConstruct
loginRecordCache = cacheManager.getCache("loginRecordCache"); public void init()
} {
loginRecordCache = cacheManager.getCache("loginRecordCache");
public void validate(User user, String password) { }
String loginName = user.getLoginName();
public void validate(User user, String password)
AtomicInteger retryCount = loginRecordCache.get(loginName); {
String loginName = user.getLoginName();
if (retryCount == null) {
retryCount = new AtomicInteger(0); AtomicInteger retryCount = loginRecordCache.get(loginName);
loginRecordCache.put(loginName, retryCount);
} if (retryCount == null)
if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue()) { {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed"), maxRetryCount)); retryCount = new AtomicInteger(0);
// SystemLogUtils.log(loginName, Constants.LOGIN_FAIL, loginRecordCache.put(loginName, retryCount);
// MessageUtils.message("user.password.retry.limit.exceed", }
// maxRetryCount)); if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue())
throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue()); {
} AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed"), maxRetryCount));
throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue());
if (!matches(user, password)) { }
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count"), retryCount, password));
// SystemLogUtils.log(loginName, Constants.LOGIN_FAIL, if (!matches(user, password))
// MessageUtils.message("user.password.retry.limit.count", {
// retryCount, password)); AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count"), retryCount, password));
loginRecordCache.put(loginName, retryCount); loginRecordCache.put(loginName, retryCount);
throw new UserPasswordNotMatchException(); throw new UserPasswordNotMatchException();
} else { }
clearLoginRecordCache(loginName); else
} {
} clearLoginRecordCache(loginName);
}
public boolean matches(User user, String newPassword) { }
return user.getPassword().equals(encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
} public boolean matches(User user, String newPassword)
{
public void clearLoginRecordCache(String username) { return user.getPassword().equals(encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
loginRecordCache.remove(username); }
}
public void clearLoginRecordCache(String username)
public String encryptPassword(String username, String password, String salt) { {
return new Md5Hash(username + password + salt).toHex().toString(); loginRecordCache.remove(username);
} }
public static void main(String[] args) { public String encryptPassword(String username, String password, String salt)
// System.out.println(new PasswordService().encryptPassword("admin", {
// "admin123", "111111")); return new Md5Hash(username + password + salt).toHex().toString();
// System.out.println(new PasswordService().encryptPassword("ry", }
// "admin123", "222222"));
} public static void main(String[] args)
{
System.out.println(new PasswordService().encryptPassword("admin", "admin123", "111111"));
System.out.println(new PasswordService().encryptPassword("ry", "admin123", "222222"));
}
} }

@ -2,12 +2,10 @@ package com.ruoyi.framework.shiro.session;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import org.apache.shiro.session.Session; import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.project.monitor.online.domain.OnlineSession; import com.ruoyi.project.monitor.online.domain.OnlineSession;
@ -19,90 +17,101 @@ import com.ruoyi.project.monitor.online.service.IUserOnlineService;
* *
* @author ruoyi * @author ruoyi
*/ */
public class OnlineSessionDAO extends EnterpriseCacheSessionDAO { public class OnlineSessionDAO extends EnterpriseCacheSessionDAO
/** {
* session 1 /**
*/ * session 1
@Value("${shiro.session.dbSyncPeriod}") */
private int dbSyncPeriod; @Value("${shiro.session.dbSyncPeriod}")
private int dbSyncPeriod;
/** /**
* *
*/ */
private static final String LAST_SYNC_DB_TIMESTAMP = OnlineSessionDAO.class.getName() + "LAST_SYNC_DB_TIMESTAMP"; private static final String LAST_SYNC_DB_TIMESTAMP = OnlineSessionDAO.class.getName() + "LAST_SYNC_DB_TIMESTAMP";
@Autowired @Autowired
private IUserOnlineService onlineService; private IUserOnlineService onlineService;
@Autowired @Autowired
private OnlineSessionFactory onlineSessionFactory; private OnlineSessionFactory onlineSessionFactory;
public OnlineSessionDAO() { public OnlineSessionDAO()
super(); {
} super();
}
public OnlineSessionDAO(long expireTime) { public OnlineSessionDAO(long expireTime)
super(); {
} super();
}
/** /**
* ID * ID
* *
* @param sessionId * @param sessionId ID
* ID * @return ShiroSession
* @return ShiroSession */
*/ @Override
@Override protected Session doReadSession(Serializable sessionId)
protected Session doReadSession(Serializable sessionId) { {
UserOnline userOnline = onlineService.selectOnlineById(String.valueOf(sessionId)); UserOnline userOnline = onlineService.selectOnlineById(String.valueOf(sessionId));
if (userOnline == null) { if (userOnline == null)
return null; {
} return null;
return onlineSessionFactory.createSession(userOnline); }
} return onlineSessionFactory.createSession(userOnline);
}
/** /**
* 访/// * 访///
*/ */
public void syncToDb(OnlineSession onlineSession) { public void syncToDb(OnlineSession onlineSession)
Date lastSyncTimestamp = (Date) onlineSession.getAttribute(LAST_SYNC_DB_TIMESTAMP); {
if (lastSyncTimestamp != null) { Date lastSyncTimestamp = (Date) onlineSession.getAttribute(LAST_SYNC_DB_TIMESTAMP);
boolean needSync = true; if (lastSyncTimestamp != null)
long deltaTime = onlineSession.getLastAccessTime().getTime() - lastSyncTimestamp.getTime(); {
if (deltaTime < dbSyncPeriod * 60 * 1000) { boolean needSync = true;
// 时间差不足 无需同步 long deltaTime = onlineSession.getLastAccessTime().getTime() - lastSyncTimestamp.getTime();
needSync = false; if (deltaTime < dbSyncPeriod * 60 * 1000)
} {
boolean isGuest = onlineSession.getUserId() == null || onlineSession.getUserId() == 0L; // 时间差不足 无需同步
needSync = false;
}
boolean isGuest = onlineSession.getUserId() == null || onlineSession.getUserId() == 0L;
// session 数据变更了 同步 // session 数据变更了 同步
if (isGuest == false && onlineSession.isAttributeChanged()) { if (isGuest == false && onlineSession.isAttributeChanged())
needSync = true; {
} needSync = true;
}
if (needSync == false) { if (needSync == false)
return; {
} return;
} }
onlineSession.setAttribute(LAST_SYNC_DB_TIMESTAMP, onlineSession.getLastAccessTime()); }
// 更新完后 重置标识 onlineSession.setAttribute(LAST_SYNC_DB_TIMESTAMP, onlineSession.getLastAccessTime());
if (onlineSession.isAttributeChanged()) { // 更新完后 重置标识
onlineSession.resetAttributeChanged(); if (onlineSession.isAttributeChanged())
} {
// onlineService.saveOnline(UserOnline.fromOnlineSession(onlineSession)); onlineSession.resetAttributeChanged();
AsyncManager.me().execute(AsyncFactory.syncSessionToDb(onlineSession)); }
} AsyncManager.me().execute(AsyncFactory.syncSessionToDb(onlineSession));
}
/** /**
* /退 * /退
*/ */
@Override @Override
protected void doDelete(Session session) { protected void doDelete(Session session)
OnlineSession onlineSession = (OnlineSession) session; {
if (null == onlineSession) { OnlineSession onlineSession = (OnlineSession) session;
return; if (null == onlineSession)
} {
onlineSession.setStatus(OnlineSession.OnlineStatus.off_line); return;
onlineService.deleteOnlineById(String.valueOf(onlineSession.getId())); }
} onlineSession.setStatus(OnlineSession.OnlineStatus.off_line);
onlineService.deleteOnlineById(String.valueOf(onlineSession.getId()));
}
} }

@ -2,12 +2,10 @@ package com.ruoyi.framework.shiro.web.filter;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import org.apache.shiro.session.SessionException; import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -21,58 +19,69 @@ import com.ruoyi.project.system.user.domain.User;
* *
* @author ruoyi * @author ruoyi
*/ */
public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter { public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
private static final Logger log = LoggerFactory.getLogger(LogoutFilter.class); {
private static final Logger log = LoggerFactory.getLogger(LogoutFilter.class);
/** /**
* 退 * 退
*/ */
private String loginUrl; private String loginUrl;
public String getLoginUrl() { public String getLoginUrl()
return loginUrl; {
} return loginUrl;
}
public void setLoginUrl(String loginUrl) { public void setLoginUrl(String loginUrl)
this.loginUrl = loginUrl; {
} this.loginUrl = loginUrl;
}
@Override @Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception
try { {
Subject subject = getSubject(request, response); try
String redirectUrl = getRedirectUrl(request, response, subject); {
try { Subject subject = getSubject(request, response);
User user = ShiroUtils.getUser(); String redirectUrl = getRedirectUrl(request, response, subject);
if (StringUtils.isNotNull(user)) { try
String loginName = user.getLoginName(); {
// 记录用户退出日志 User user = ShiroUtils.getUser();
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGOUT, MessageUtils.message("user.logout.success"))); if (StringUtils.isNotNull(user))
// SystemLogUtils.log(loginName, Constants.LOGOUT, {
// MessageUtils.message("user.logout.success")); String loginName = user.getLoginName();
} // 记录用户退出日志
// 退出登录 AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
subject.logout(); }
} catch (SessionException ise) { // 退出登录
log.error("logout fail.", ise); subject.logout();
} }
issueRedirect(request, response, redirectUrl); catch (SessionException ise)
} catch (Exception e) { {
log.error("Encountered session exception during logout. This can generally safely be ignored.", e); log.error("logout fail.", ise);
} }
return false; issueRedirect(request, response, redirectUrl);
} }
catch (Exception e)
{
log.error("Encountered session exception during logout. This can generally safely be ignored.", e);
}
return false;
}
/** /**
* 退URL * 退URL
*/ */
@Override @Override
protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject) { protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject)
String url = getLoginUrl(); {
if (StringUtils.isNotEmpty(url)) { String url = getLoginUrl();
return url; if (StringUtils.isNotEmpty(url))
} {
return super.getRedirectUrl(request, response, subject); return url;
} }
return super.getRedirectUrl(request, response, subject);
}
} }

@ -1,8 +1,6 @@
package com.ruoyi.project.monitor.online.domain; package com.ruoyi.project.monitor.online.domain;
import java.util.Date; import java.util.Date;
import com.ruoyi.common.utils.AddressUtils;
import com.ruoyi.framework.web.domain.BaseEntity; import com.ruoyi.framework.web.domain.BaseEntity;
import com.ruoyi.project.monitor.online.domain.OnlineSession.OnlineStatus; import com.ruoyi.project.monitor.online.domain.OnlineSession.OnlineStatus;
@ -11,164 +9,172 @@ import com.ruoyi.project.monitor.online.domain.OnlineSession.OnlineStatus;
* *
* @author ruoyi * @author ruoyi
*/ */
public class UserOnline extends BaseEntity { public class UserOnline extends BaseEntity
private static final long serialVersionUID = 1L; {
/** 用户会话id */ private static final long serialVersionUID = 1L;
private String sessionId; /** 用户会话id */
private String sessionId;
/** 部门名称 */
private String deptName; /** 部门名称 */
private String deptName;
/** 登录名称 */
private String loginName; /** 登录名称 */
private String loginName;
/** 登录IP地址 */
private String ipaddr; /** 登录IP地址 */
private String ipaddr;
/** 登录地址 */
private String longinLocation; /** 登录地址 */
private String longinLocation;
/** 浏览器类型 */
private String browser; /** 浏览器类型 */
private String browser;
/** 操作系统 */
private String os; /** 操作系统 */
private String os;
/** session创建时间 */
private Date startTimestamp; /** session创建时间 */
private Date startTimestamp;
/** session最后访问时间 */
private Date lastAccessTime; /** session最后访问时间 */
private Date lastAccessTime;
/** 超时时间,单位为分钟 */
private Long expireTime; /** 超时时间,单位为分钟 */
private Long expireTime;
/** 在线状态 */
private OnlineStatus status = OnlineStatus.on_line; /** 在线状态 */
private OnlineStatus status = OnlineStatus.on_line;
/** 备份的当前用户会话 */
private OnlineSession session; /** 备份的当前用户会话 */
private OnlineSession session;
/**
* session public String getSessionId()
*/ {
@Deprecated return sessionId;
public static final UserOnline fromOnlineSession(OnlineSession session) { }
UserOnline online = new UserOnline();
online.setSessionId(String.valueOf(session.getId())); public void setSessionId(String sessionId)
online.setDeptName(session.getDeptName()); {
online.setLoginName(session.getLoginName()); this.sessionId = sessionId;
online.setStartTimestamp(session.getStartTimestamp()); }
online.setLastAccessTime(session.getLastAccessTime());
online.setExpireTime(session.getTimeout()); public String getDeptName()
online.setIpaddr(session.getHost()); {
online.setLonginLocation(AddressUtils.getRealAddressByIP(session.getHost())); return deptName;
online.setBrowser(session.getBrowser()); }
online.setOs(session.getOs());
online.setStatus(session.getStatus()); public void setDeptName(String deptName)
online.setSession(session); {
return online; this.deptName = deptName;
} }
public String getSessionId() { public String getLoginName()
return sessionId; {
} return loginName;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId; public void setLoginName(String loginName)
} {
this.loginName = loginName;
public String getDeptName() { }
return deptName;
} public String getIpaddr()
{
public void setDeptName(String deptName) { return ipaddr;
this.deptName = deptName; }
}
public void setIpaddr(String ipaddr)
public String getLoginName() { {
return loginName; this.ipaddr = ipaddr;
} }
public void setLoginName(String loginName) { public String getLonginLocation()
this.loginName = loginName; {
} return longinLocation;
}
public String getIpaddr() {
return ipaddr; public void setLonginLocation(String longinLocation)
} {
this.longinLocation = longinLocation;
public void setIpaddr(String ipaddr) { }
this.ipaddr = ipaddr;
} public String getBrowser()
{
public String getLonginLocation() { return browser;
return longinLocation; }
}
public void setBrowser(String browser)
public void setLonginLocation(String longinLocation) { {
this.longinLocation = longinLocation; this.browser = browser;
} }
public String getBrowser() { public String getOs()
return browser; {
} return os;
}
public void setBrowser(String browser) {
this.browser = browser; public void setOs(String os)
} {
this.os = os;
public String getOs() { }
return os;
} public Date getStartTimestamp()
{
public void setOs(String os) { return startTimestamp;
this.os = os; }
}
public void setStartTimestamp(Date startTimestamp)
public Date getStartTimestamp() { {
return startTimestamp; this.startTimestamp = startTimestamp;
} }
public void setStartTimestamp(Date startTimestamp) { public Date getLastAccessTime()
this.startTimestamp = startTimestamp; {
} return lastAccessTime;
}
public Date getLastAccessTime() {
return lastAccessTime; public void setLastAccessTime(Date lastAccessTime)
} {
this.lastAccessTime = lastAccessTime;
public void setLastAccessTime(Date lastAccessTime) { }
this.lastAccessTime = lastAccessTime;
} public Long getExpireTime()
{
public Long getExpireTime() { return expireTime;
return expireTime; }
}
public void setExpireTime(Long expireTime)
public void setExpireTime(Long expireTime) { {
this.expireTime = expireTime; this.expireTime = expireTime;
} }
public OnlineStatus getStatus() { public OnlineStatus getStatus()
return status; {
} return status;
}
public void setStatus(OnlineStatus status) {
this.status = status; public void setStatus(OnlineStatus status)
} {
this.status = status;
public OnlineSession getSession() { }
return session;
} public OnlineSession getSession()
{
public void setSession(OnlineSession session) { return session;
this.session = session; }
}
public void setSession(OnlineSession session)
@Override {
public String toString() { this.session = session;
return "UserOnline [sessionId=" + sessionId + ", deptName=" + deptName + ", loginName=" + loginName + ", ipaddr=" + ipaddr + ", browser=" + browser + ", os=" + os + ", startTimestamp=" + startTimestamp + ", lastAccessTime=" + lastAccessTime + ", expireTime=" + expireTime + ", status=" + status + ", session=" + session + "]"; }
}
@Override
public String toString()
{
return "UserOnline [sessionId=" + sessionId + ", deptName=" + deptName + ", loginName=" + loginName
+ ", ipaddr=" + ipaddr + ", browser=" + browser + ", os=" + os + ", startTimestamp=" + startTimestamp
+ ", lastAccessTime=" + lastAccessTime + ", expireTime=" + expireTime + ", status=" + status
+ ", session=" + session + "]";
}
} }

Loading…
Cancel
Save