This commit is contained in:
tony
2023-02-22 17:36:28 +08:00
52 changed files with 423 additions and 156 deletions

View File

@@ -4,12 +4,15 @@ import java.util.Collection;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
@@ -41,6 +44,18 @@ public class LogAspect
/** 排除敏感属性字段 */
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
/** 计算操作消耗时间 */
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
/**
* 处理请求前执行
*/
@Before(value = "@annotation(controllerLog)")
public void boBefore(JoinPoint joinPoint, Log controllerLog)
{
TIME_THREADLOCAL.set(System.currentTimeMillis());
}
/**
* 处理完请求后执行
*
@@ -75,7 +90,7 @@ public class LogAspect
SysOperLog operLog = new SysOperLog();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
// 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
String ip = IpUtils.getIpAddr();
operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
if (loginUser != null)
@@ -96,6 +111,8 @@ public class LogAspect
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 设置消耗时间
operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
// 保存数据库
AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
}
@@ -105,6 +122,10 @@ public class LogAspect
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
}
finally
{
TIME_THREADLOCAL.remove();
}
}
/**
@@ -126,7 +147,7 @@ public class LogAspect
if (log.isSaveRequestData())
{
// 获取参数的信息,传入到数据库中。
setRequestValue(joinPoint, operLog);
setRequestValue(joinPoint, operLog, log.excludeParamNames());
}
// 是否需要保存response参数和值
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult))
@@ -141,25 +162,25 @@ public class LogAspect
* @param operLog 操作日志
* @throws Exception 异常
*/
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
{
String requestMethod = operLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
{
String params = argsArrayToString(joinPoint.getArgs());
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
}
else
{
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter()), 0, 2000));
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
}
}
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray)
private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
{
String params = "";
if (paramsArray != null && paramsArray.length > 0)
@@ -170,7 +191,7 @@ public class LogAspect
{
try
{
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter());
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
params += jsonObj.toString() + " ";
}
catch (Exception e)
@@ -185,9 +206,9 @@ public class LogAspect
/**
* 忽略敏感属性
*/
public PropertyPreExcludeFilter excludePropertyPreFilter()
public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames)
{
return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES);
return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
}
/**

View File

@@ -16,7 +16,6 @@ import org.springframework.stereotype.Component;
import com.ruoyi.common.annotation.RateLimiter;
import com.ruoyi.common.enums.LimitType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
@@ -79,7 +78,7 @@ public class RateLimiterAspect
StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
if (rateLimiter.limitType() == LimitType.IP)
{
stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())).append("-");
stringBuffer.append(IpUtils.getIpAddr()).append("-");
}
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();

View File

@@ -38,7 +38,7 @@ public class AsyncFactory
final Object... args)
{
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
final String ip = IpUtils.getIpAddr();
return new TimerTask()
{
@Override

View File

@@ -117,7 +117,7 @@ public class Jvm
*/
public String getRunTime()
{
return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
return DateUtils.timeDistance(DateUtils.getNowDate(), DateUtils.getServerStartDate());
}
/**

View File

@@ -9,16 +9,18 @@ import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.BlackListException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.exception.user.UserNotExistsException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.manager.AsyncManager;
@@ -61,12 +63,10 @@ public class SysLoginService
*/
public String login(String username, String password, String code, String uuid)
{
boolean captchaEnabled = configService.selectCaptchaEnabled();
// 验证码开关
if (captchaEnabled)
{
validateCaptcha(username, code, uuid);
}
// 验证码校验
validateCaptcha(username, code, uuid);
// 登录前置校验
loginPreCheck(username, password);
// 用户验证
Authentication authentication = null;
try
@@ -110,18 +110,58 @@ public class SysLoginService
*/
public void validateCaptcha(String username, String code, String uuid)
{
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null)
boolean captchaEnabled = configService.selectCaptchaEnabled();
if (captchaEnabled)
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null)
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
throw new CaptchaException();
}
}
if (!code.equalsIgnoreCase(captcha))
}
/**
* 登录前置校验
* @param username 用户名
* @param password 用户密码
*/
public void loginPreCheck(String username, String password)
{
// 用户名或密码为空 错误
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
throw new CaptchaException();
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
throw new UserNotExistsException();
}
// 密码如果不在指定范围内 错误
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")));
throw new UserPasswordNotMatchException();
}
// 用户名不在指定范围内 错误
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")));
throw new UserPasswordNotMatchException();
}
// IP黑名单校验
String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
throw new BlackListException();
}
}
@@ -134,7 +174,7 @@ public class SysLoginService
{
SysUser sysUser = new SysUser();
sysUser.setUserId(userId);
sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
sysUser.setLoginIp(IpUtils.getIpAddr());
sysUser.setLoginDate(DateUtils.getNowDate());
userService.updateUserProfile(sysUser);
}

View File

@@ -69,7 +69,7 @@ public class SysRegisterService
{
msg = "密码长度必须在5到20个字符之间";
}
else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser)))
else if (!userService.checkUserNameUnique(sysUser))
{
msg = "保存用户'" + username + "'失败,注册账号已存在";
}

View File

@@ -156,7 +156,7 @@ public class TokenService
public void setUserAgent(LoginUser loginUser)
{
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
String ip = IpUtils.getIpAddr();
loginUser.setIpaddr(ip);
loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
loginUser.setBrowser(userAgent.getBrowser().getName());