Commit e93e0c4c by RuoYi

format

parent f9c82e1f
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; ...@@ -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; ...@@ -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,22 +33,24 @@ import com.ruoyi.project.system.user.domain.User; ...@@ -35,22 +33,24 @@ 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)") @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.Log)")
public void logPointCut() { public void logPointCut()
{
} }
/** /**
* 前置通知 用于拦截操作 * 前置通知 用于拦截操作
* *
* @param joinPoint * @param joinPoint 切点
* 切点
*/ */
@AfterReturning(pointcut = "logPointCut()") @AfterReturning(pointcut = "logPointCut()")
public void doBefore(JoinPoint joinPoint) { public void doBefore(JoinPoint joinPoint)
{
handleLog(joinPoint, null); handleLog(joinPoint, null);
} }
...@@ -61,16 +61,20 @@ public class LogAspect { ...@@ -61,16 +61,20 @@ public class LogAspect {
* @param e * @param e
*/ */
@AfterThrowing(value = "logPointCut()", throwing = "e") @AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfter(JoinPoint joinPoint, Exception e) { public void doAfter(JoinPoint joinPoint, Exception e)
{
handleLog(joinPoint, e); handleLog(joinPoint, e);
} }
@Async @Async
protected void handleLog(final JoinPoint joinPoint, final Exception e) { protected void handleLog(final JoinPoint joinPoint, final Exception e)
try { {
try
{
// 获得注解 // 获得注解
Log controllerLog = getAnnotationLog(joinPoint); Log controllerLog = getAnnotationLog(joinPoint);
if (controllerLog == null) { if (controllerLog == null)
{
return; return;
} }
...@@ -85,14 +89,18 @@ public class LogAspect { ...@@ -85,14 +89,18 @@ public class LogAspect {
operLog.setOperIp(ip); operLog.setOperIp(ip);
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
if (currentUser != null) { if (currentUser != null)
{
operLog.setOperName(currentUser.getLoginName()); operLog.setOperName(currentUser.getLoginName());
if (StringUtils.isNotNull(currentUser.getDept()) && StringUtils.isNotEmpty(currentUser.getDept().getDeptName())) { if (StringUtils.isNotNull(currentUser.getDept())
&& StringUtils.isNotEmpty(currentUser.getDept().getDeptName()))
{
operLog.setDeptName(currentUser.getDept().getDeptName()); operLog.setDeptName(currentUser.getDept().getDeptName());
} }
} }
if (e != null) { if (e != null)
{
operLog.setStatus(BusinessStatus.FAIL); operLog.setStatus(BusinessStatus.FAIL);
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
} }
...@@ -104,7 +112,9 @@ public class LogAspect { ...@@ -104,7 +112,9 @@ public class LogAspect {
getControllerMethodDescription(controllerLog, operLog); getControllerMethodDescription(controllerLog, operLog);
// 保存数据库 // 保存数据库
AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
} catch (Exception exp) { }
catch (Exception exp)
{
// 记录本地异常日志 // 记录本地异常日志
log.error("==前置通知异常=="); log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage()); log.error("异常信息:{}", exp.getMessage());
...@@ -115,12 +125,12 @@ public class LogAspect { ...@@ -115,12 +125,12 @@ public class LogAspect {
/** /**
* 获取注解中对方法的描述信息 用于Controller层注解 * 获取注解中对方法的描述信息 用于Controller层注解
* *
* @param joinPoint * @param joinPoint 切点
* 切点
* @return 方法描述 * @return 方法描述
* @throws Exception * @throws Exception
*/ */
public void getControllerMethodDescription(Log log, OperLog operLog) throws Exception { public void getControllerMethodDescription(Log log, OperLog operLog) throws Exception
{
// 设置action动作 // 设置action动作
operLog.setAction(log.action()); operLog.setAction(log.action());
// 设置标题 // 设置标题
...@@ -128,7 +138,8 @@ public class LogAspect { ...@@ -128,7 +138,8 @@ public class LogAspect {
// 设置channel // 设置channel
operLog.setChannel(log.channel()); operLog.setChannel(log.channel());
// 是否需要保存request,参数和值 // 是否需要保存request,参数和值
if (log.isSaveRequestData()) { if (log.isSaveRequestData())
{
// 获取参数的信息,传入到数据库中。 // 获取参数的信息,传入到数据库中。
setRequestValue(operLog); setRequestValue(operLog);
} }
...@@ -140,7 +151,8 @@ public class LogAspect { ...@@ -140,7 +151,8 @@ public class LogAspect {
* @param operLog * @param operLog
* @param request * @param request
*/ */
private void setRequestValue(OperLog operLog) { private void setRequestValue(OperLog operLog)
{
Map<String, String[]> map = ServletUtils.getRequest().getParameterMap(); Map<String, String[]> map = ServletUtils.getRequest().getParameterMap();
String params = JSONObject.toJSONString(map); String params = JSONObject.toJSONString(map);
operLog.setOperParam(StringUtils.substring(params, 0, 255)); operLog.setOperParam(StringUtils.substring(params, 0, 255));
...@@ -149,12 +161,14 @@ public class LogAspect { ...@@ -149,12 +161,14 @@ public class LogAspect {
/** /**
* 是否存在注解,如果存在就获取 * 是否存在注解,如果存在就获取
*/ */
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception { private Log getAnnotationLog(JoinPoint joinPoint) throws Exception
{
Signature signature = joinPoint.getSignature(); Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature; MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod(); Method method = methodSignature.getMethod();
if (method != null) { if (method != null)
{
return method.getAnnotation(Log.class); return method.getAnnotation(Log.class);
} }
return null; return null;
......
...@@ -9,18 +9,35 @@ import java.util.concurrent.TimeUnit; ...@@ -9,18 +9,35 @@ import java.util.concurrent.TimeUnit;
* *
* @author liuhulu * @author liuhulu
*/ */
public class AsyncManager { public class AsyncManager
// 操作延迟 {
/**
* 操作延迟10毫秒
*/
private final int OPERATE_DELAY_TIME = 10; private final int OPERATE_DELAY_TIME = 10;
// 异步操作此案城池
/**
* 异步操作任务调度线程池
*/
private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5); private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5);
// 单例
/**
* 单例模式
*/
private static AsyncManager me = new AsyncManager(); private static AsyncManager me = new AsyncManager();
public static AsyncManager me() {
public static AsyncManager me()
{
return me; return me;
} }
// 执行任务
public void execute(TimerTask task) { /**
* 执行任务
*
* @param 任务task
*/
public void execute(TimerTask task)
{
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
} }
} }
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; ...@@ -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,19 +24,23 @@ import eu.bitwalker.useragentutils.UserAgent; ...@@ -27,19 +24,23 @@ 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() { {
return new TimerTask()
{
@Override @Override
public void run() { public void run()
{
UserOnline online = new UserOnline(); UserOnline online = new UserOnline();
online.setSessionId(String.valueOf(session.getId())); online.setSessionId(String.valueOf(session.getId()));
online.setDeptName(session.getDeptName()); online.setDeptName(session.getDeptName());
...@@ -58,16 +59,20 @@ public class AsyncFactory { ...@@ -58,16 +59,20 @@ public class AsyncFactory {
} }
}; };
} }
/** /**
* 记录 操作log * 操作日志记录
* *
* @param rc * @param operLog 操作日志信息
* @return * @return 任务task
*/ */
public static TimerTask recordOper(final OperLog operLog) { public static TimerTask recordOper(final OperLog operLog)
return new TimerTask() { {
return new TimerTask()
{
@Override @Override
public void run() { public void run()
{
// 远程查询操作地点 // 远程查询操作地点
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
SpringUtils.getBean(IOperLogService.class).insertOperlog(operLog); SpringUtils.getBean(IOperLogService.class).insertOperlog(operLog);
...@@ -78,18 +83,20 @@ public class AsyncFactory { ...@@ -78,18 +83,20 @@ public class AsyncFactory {
/** /**
* 记录登陆信息 * 记录登陆信息
* *
* @param username * @param username 用户名
* @param status * @param status 状态
* @param message * @param message 消息
* @param userAgent * @param args 列表
* @param args * @return 任务task
* @return
*/ */
public static TimerTask recordLogininfor(final String username, final String status, final String message, final Object... args) { 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 UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
return new TimerTask() { return new TimerTask()
{
@Override @Override
public void run() { public void run()
{
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
s.append(LogUtils.getBlock(ShiroUtils.getIp())); s.append(LogUtils.getBlock(ShiroUtils.getIp()));
s.append(AddressUtils.getRealAddressByIP(ShiroUtils.getIp())); s.append(AddressUtils.getRealAddressByIP(ShiroUtils.getIp()));
...@@ -111,9 +118,12 @@ public class AsyncFactory { ...@@ -111,9 +118,12 @@ public class AsyncFactory {
logininfor.setOs(os); logininfor.setOs(os);
logininfor.setMsg(message); logininfor.setMsg(message);
// 日志状态 // 日志状态
if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) { if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
{
logininfor.setStatus(Constants.SUCCESS); logininfor.setStatus(Constants.SUCCESS);
} else if (Constants.LOGIN_FAIL.equals(status)) { }
else if (Constants.LOGIN_FAIL.equals(status))
{
logininfor.setStatus(Constants.FAIL); logininfor.setStatus(Constants.FAIL);
} }
// 插入数据 // 插入数据
...@@ -121,5 +131,4 @@ public class AsyncFactory { ...@@ -121,5 +131,4 @@ public class AsyncFactory {
} }
}; };
} }
} }
...@@ -3,7 +3,6 @@ package com.ruoyi.framework.shiro.service; ...@@ -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,7 +26,8 @@ import com.ruoyi.project.system.user.service.IUserService; ...@@ -27,7 +26,8 @@ import com.ruoyi.project.system.user.service.IUserService;
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class LoginService { public class LoginService
{
@Autowired @Autowired
private PasswordService passwordService; private PasswordService passwordService;
...@@ -37,79 +37,80 @@ public class LoginService { ...@@ -37,79 +37,80 @@ public class LoginService {
/** /**
* 登录 * 登录
*/ */
public User login(String username, String password) { public User login(String username, String password)
{
// 验证码校验 // 验证码校验
if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA))) { if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
// SystemLogUtils.log(username, Constants.LOGIN_FAIL,
// MessageUtils.message("user.jcaptcha.error"));
throw new CaptchaException(); throw new CaptchaException();
} }
// 用户名或密码为空 错误 // 用户名或密码为空 错误
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
// SystemLogUtils.log(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
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(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")));
// SystemLogUtils.log(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
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(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")));
// SystemLogUtils.log(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)) { if (user == null && maybeEmail(username))
{
user = userService.selectUserByEmail(username); user = userService.selectUserByEmail(username);
} }
if (user == null || UserStatus.DELETED.getCode().equals(user.getDelFlag())) { if (user == null || UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
// SystemLogUtils.log(username, Constants.LOGIN_FAIL,
// MessageUtils.message("user.not.exists"));
throw new UserNotExistsException(); throw new UserNotExistsException();
} }
passwordService.validate(user, password); passwordService.validate(user, password);
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(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())));
// SystemLogUtils.log(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,
// MessageUtils.message("user.login.success"));
recordLoginInfo(user); recordLoginInfo(user);
return 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)) { {
if (!username.matches(UserConstants.MOBILE_PHONE_NUMBER_PATTERN))
{
return false; return false;
} }
return true; return true;
...@@ -118,7 +119,8 @@ public class LoginService { ...@@ -118,7 +119,8 @@ public class LoginService {
/** /**
* 记录登录信息 * 记录登录信息
*/ */
public void recordLoginInfo(User user) { public void recordLoginInfo(User user)
{
user.setLoginIp(ShiroUtils.getIp()); user.setLoginIp(ShiroUtils.getIp());
user.setLoginDate(DateUtils.getNowDate()); user.setLoginDate(DateUtils.getNowDate());
userService.updateUserInfo(user); userService.updateUserInfo(user);
......
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,7 +22,8 @@ import com.ruoyi.project.system.user.domain.User; ...@@ -25,7 +22,8 @@ import com.ruoyi.project.system.user.domain.User;
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class PasswordService { public class PasswordService
{
@Autowired @Autowired
private CacheManager cacheManager; private CacheManager cacheManager;
...@@ -36,55 +34,58 @@ public class PasswordService { ...@@ -36,55 +34,58 @@ public class PasswordService {
private String maxRetryCount; private String maxRetryCount;
@PostConstruct @PostConstruct
public void init() { public void init()
{
loginRecordCache = cacheManager.getCache("loginRecordCache"); loginRecordCache = cacheManager.getCache("loginRecordCache");
} }
public void validate(User user, String password) { public void validate(User user, String password)
{
String loginName = user.getLoginName(); String loginName = user.getLoginName();
AtomicInteger retryCount = loginRecordCache.get(loginName); AtomicInteger retryCount = loginRecordCache.get(loginName);
if (retryCount == null) { if (retryCount == null)
{
retryCount = new AtomicInteger(0); retryCount = new AtomicInteger(0);
loginRecordCache.put(loginName, retryCount); loginRecordCache.put(loginName, retryCount);
} }
if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue()) { if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue())
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed"), maxRetryCount)); AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed"), maxRetryCount));
// SystemLogUtils.log(loginName, Constants.LOGIN_FAIL,
// MessageUtils.message("user.password.retry.limit.exceed",
// maxRetryCount));
throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue()); throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue());
} }
if (!matches(user, password)) { if (!matches(user, password))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, 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));
// SystemLogUtils.log(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 { }
else
{
clearLoginRecordCache(loginName); clearLoginRecordCache(loginName);
} }
} }
public boolean matches(User user, String newPassword) { public boolean matches(User user, String newPassword)
{
return user.getPassword().equals(encryptPassword(user.getLoginName(), newPassword, user.getSalt())); return user.getPassword().equals(encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
} }
public void clearLoginRecordCache(String username) { public void clearLoginRecordCache(String username)
{
loginRecordCache.remove(username); loginRecordCache.remove(username);
} }
public String encryptPassword(String username, String password, String salt) { public String encryptPassword(String username, String password, String salt)
{
return new Md5Hash(username + password + salt).toHex().toString(); return new Md5Hash(username + password + salt).toHex().toString();
} }
public static void main(String[] args) { public static void main(String[] args)
// System.out.println(new PasswordService().encryptPassword("admin", {
// "admin123", "111111")); System.out.println(new PasswordService().encryptPassword("admin", "admin123", "111111"));
// System.out.println(new PasswordService().encryptPassword("ry", System.out.println(new PasswordService().encryptPassword("ry", "admin123", "222222"));
// "admin123", "222222"));
} }
} }
...@@ -2,12 +2,10 @@ package com.ruoyi.framework.shiro.session; ...@@ -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,7 +17,8 @@ import com.ruoyi.project.monitor.online.service.IUserOnlineService; ...@@ -19,7 +17,8 @@ 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分钟)
*/ */
...@@ -37,25 +36,28 @@ public class OnlineSessionDAO extends EnterpriseCacheSessionDAO { ...@@ -37,25 +36,28 @@ public class OnlineSessionDAO extends EnterpriseCacheSessionDAO {
@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);
...@@ -64,32 +66,37 @@ public class OnlineSessionDAO extends EnterpriseCacheSessionDAO { ...@@ -64,32 +66,37 @@ public class OnlineSessionDAO extends EnterpriseCacheSessionDAO {
/** /**
* 更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用 * 更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用
*/ */
public void syncToDb(OnlineSession onlineSession) { public void syncToDb(OnlineSession onlineSession)
{
Date lastSyncTimestamp = (Date) onlineSession.getAttribute(LAST_SYNC_DB_TIMESTAMP); Date lastSyncTimestamp = (Date) onlineSession.getAttribute(LAST_SYNC_DB_TIMESTAMP);
if (lastSyncTimestamp != null) { if (lastSyncTimestamp != null)
{
boolean needSync = true; boolean needSync = true;
long deltaTime = onlineSession.getLastAccessTime().getTime() - lastSyncTimestamp.getTime(); long deltaTime = onlineSession.getLastAccessTime().getTime() - lastSyncTimestamp.getTime();
if (deltaTime < dbSyncPeriod * 60 * 1000) { if (deltaTime < dbSyncPeriod * 60 * 1000)
{
// 时间差不足 无需同步 // 时间差不足 无需同步
needSync = false; needSync = false;
} }
boolean isGuest = onlineSession.getUserId() == null || onlineSession.getUserId() == 0L; 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()) { if (onlineSession.isAttributeChanged())
{
onlineSession.resetAttributeChanged(); onlineSession.resetAttributeChanged();
} }
// onlineService.saveOnline(UserOnline.fromOnlineSession(onlineSession));
AsyncManager.me().execute(AsyncFactory.syncSessionToDb(onlineSession)); AsyncManager.me().execute(AsyncFactory.syncSessionToDb(onlineSession));
} }
...@@ -97,9 +104,11 @@ public class OnlineSessionDAO extends EnterpriseCacheSessionDAO { ...@@ -97,9 +104,11 @@ public class OnlineSessionDAO extends EnterpriseCacheSessionDAO {
* 当会话过期/停止(如用户退出时)属性等会调用 * 当会话过期/停止(如用户退出时)属性等会调用
*/ */
@Override @Override
protected void doDelete(Session session) { protected void doDelete(Session session)
{
OnlineSession onlineSession = (OnlineSession) session; OnlineSession onlineSession = (OnlineSession) session;
if (null == onlineSession) { if (null == onlineSession)
{
return; return;
} }
onlineSession.setStatus(OnlineSession.OnlineStatus.off_line); onlineSession.setStatus(OnlineSession.OnlineStatus.off_line);
......
...@@ -2,12 +2,10 @@ package com.ruoyi.framework.shiro.web.filter; ...@@ -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,7 +19,8 @@ import com.ruoyi.project.system.user.domain.User; ...@@ -21,7 +19,8 @@ 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);
/** /**
...@@ -29,35 +28,43 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter ...@@ -29,35 +28,43 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
*/ */
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 { {
try
{
Subject subject = getSubject(request, response); Subject subject = getSubject(request, response);
String redirectUrl = getRedirectUrl(request, response, subject); String redirectUrl = getRedirectUrl(request, response, subject);
try { try
{
User user = ShiroUtils.getUser(); User user = ShiroUtils.getUser();
if (StringUtils.isNotNull(user)) { if (StringUtils.isNotNull(user))
{
String loginName = user.getLoginName(); String loginName = user.getLoginName();
// 记录用户退出日志 // 记录用户退出日志
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGOUT, MessageUtils.message("user.logout.success"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
// SystemLogUtils.log(loginName, Constants.LOGOUT,
// MessageUtils.message("user.logout.success"));
} }
// 退出登录 // 退出登录
subject.logout(); subject.logout();
} catch (SessionException ise) { }
catch (SessionException ise)
{
log.error("logout fail.", ise); log.error("logout fail.", ise);
} }
issueRedirect(request, response, redirectUrl); issueRedirect(request, response, redirectUrl);
} catch (Exception e) { }
catch (Exception e)
{
log.error("Encountered session exception during logout. This can generally safely be ignored.", e); log.error("Encountered session exception during logout. This can generally safely be ignored.", e);
} }
return false; return false;
...@@ -67,9 +74,11 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter ...@@ -67,9 +74,11 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
* 退出跳转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(); String url = getLoginUrl();
if (StringUtils.isNotEmpty(url)) { if (StringUtils.isNotEmpty(url))
{
return url; return url;
} }
return super.getRedirectUrl(request, response, subject); return super.getRedirectUrl(request, response, subject);
......
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,7 +9,8 @@ import com.ruoyi.project.monitor.online.domain.OnlineSession.OnlineStatus; ...@@ -11,7 +9,8 @@ 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; private static final long serialVersionUID = 1L;
/** 用户会话id */ /** 用户会话id */
private String sessionId; private String sessionId;
...@@ -49,126 +48,133 @@ public class UserOnline extends BaseEntity { ...@@ -49,126 +48,133 @@ public class UserOnline extends BaseEntity {
/** 备份的当前用户会话 */ /** 备份的当前用户会话 */
private OnlineSession session; private OnlineSession session;
/** public String getSessionId()
* 设置session对象 {
*/
@Deprecated
public static final UserOnline fromOnlineSession(OnlineSession session) {
UserOnline online = new UserOnline();
online.setSessionId(String.valueOf(session.getId()));
online.setDeptName(session.getDeptName());
online.setLoginName(session.getLoginName());
online.setStartTimestamp(session.getStartTimestamp());
online.setLastAccessTime(session.getLastAccessTime());
online.setExpireTime(session.getTimeout());
online.setIpaddr(session.getHost());
online.setLonginLocation(AddressUtils.getRealAddressByIP(session.getHost()));
online.setBrowser(session.getBrowser());
online.setOs(session.getOs());
online.setStatus(session.getStatus());
online.setSession(session);
return online;
}
public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(String sessionId) { public void setSessionId(String sessionId)
{
this.sessionId = sessionId; this.sessionId = sessionId;
} }
public String getDeptName() { public String getDeptName()
{
return deptName; return deptName;
} }
public void setDeptName(String deptName) { public void setDeptName(String deptName)
{
this.deptName = deptName; this.deptName = deptName;
} }
public String getLoginName() { public String getLoginName()
{
return loginName; return loginName;
} }
public void setLoginName(String loginName) { public void setLoginName(String loginName)
{
this.loginName = loginName; this.loginName = loginName;
} }
public String getIpaddr() { public String getIpaddr()
{
return ipaddr; return ipaddr;
} }
public void setIpaddr(String ipaddr) { public void setIpaddr(String ipaddr)
{
this.ipaddr = ipaddr; this.ipaddr = ipaddr;
} }
public String getLonginLocation() { public String getLonginLocation()
{
return longinLocation; return longinLocation;
} }
public void setLonginLocation(String longinLocation) { public void setLonginLocation(String longinLocation)
{
this.longinLocation = longinLocation; this.longinLocation = longinLocation;
} }
public String getBrowser() { public String getBrowser()
{
return browser; return browser;
} }
public void setBrowser(String browser) { public void setBrowser(String browser)
{
this.browser = browser; this.browser = browser;
} }
public String getOs() { public String getOs()
{
return os; return os;
} }
public void setOs(String os) { public void setOs(String os)
{
this.os = os; this.os = os;
} }
public Date getStartTimestamp() { public Date getStartTimestamp()
{
return startTimestamp; return startTimestamp;
} }
public void setStartTimestamp(Date startTimestamp) { public void setStartTimestamp(Date startTimestamp)
{
this.startTimestamp = startTimestamp; this.startTimestamp = startTimestamp;
} }
public Date getLastAccessTime() { public Date getLastAccessTime()
{
return lastAccessTime; return lastAccessTime;
} }
public void setLastAccessTime(Date lastAccessTime) { public void setLastAccessTime(Date lastAccessTime)
{
this.lastAccessTime = 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) { public void setStatus(OnlineStatus status)
{
this.status = status; this.status = status;
} }
public OnlineSession getSession() { public OnlineSession getSession()
{
return session; return session;
} }
public void setSession(OnlineSession session) { public void setSession(OnlineSession session)
{
this.session = session; this.session = session;
} }
@Override @Override
public String toString() { 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 + "]"; {
return "UserOnline [sessionId=" + sessionId + ", deptName=" + deptName + ", loginName=" + loginName
+ ", ipaddr=" + ipaddr + ", browser=" + browser + ", os=" + os + ", startTimestamp=" + startTimestamp
+ ", lastAccessTime=" + lastAccessTime + ", expireTime=" + expireTime + ", status=" + status
+ ", session=" + session + "]";
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment