增加签名和限流日志

This commit is contained in:
2023-11-29 17:04:15 +08:00
parent b6535a2efc
commit eb62acff5f
3 changed files with 85 additions and 15 deletions

View File

@@ -5,7 +5,10 @@ import cn.lihongjie.coal.common.Constants;
import cn.lihongjie.coal.common.Ctx;
import cn.lihongjie.coal.common.RequestUtils;
import cn.lihongjie.coal.exception.BizException;
import cn.lihongjie.coal.ip.IpQueryService;
import cn.lihongjie.coal.loginUser.service.LoginUserService;
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
import cn.lihongjie.coal.syslog.service.SysLogService;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -39,6 +42,10 @@ public class RateLimitFilter extends OncePerRequestFilter {
@Autowired ObjectMapper objectMapper;
@Autowired RedissonClient redissonClient;
@Autowired SysLogService sysLogService;
@Autowired IpQueryService ipQueryService;
@Autowired LoginUserService loginUserService;
@Override
public void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -49,38 +56,46 @@ public class RateLimitFilter extends OncePerRequestFilter {
String ip = RequestUtils.getIp(request);
if (StringUtils.isAllBlank(ip, sessionId)) {
sysLogService.saveSysLog(request, "限流模块", "非法请求", "ip和sessionId都为空");
writeResponse(new BizException("非法请求"), response);
return;
}
if (StringUtils.isNotEmpty(sessionId)) {
RRateLimiter sessionRL = redissonClient.getRateLimiter(Constants.RATE_LIMIT_GLOBAL_SESSION_PREFIX + sessionId);
RRateLimiter sessionRL =
redissonClient.getRateLimiter(
Constants.RATE_LIMIT_GLOBAL_SESSION_PREFIX + sessionId);
boolean acquire = sessionRL.tryAcquire(1);
if (!acquire) {
sysLogService.saveSysLog(request, "限流模块", "会话限流", "");
writeResponse(new BizException("当前会话请求被限流,请稍后再试"), response);
log.warn("会话限流: sessionId {} user {} request {}", sessionId, Ctx.currentUser().getUsername(), request.getRequestURI());
log.warn(
"会话限流: sessionId {} user {} request {}",
sessionId,
Ctx.currentUser().getUsername(),
request.getRequestURI());
return;
}
RRateLimiter userRL = redissonClient.getRateLimiter(Constants.RATE_LIMIT_GLOBAL_USER_PREFIX + Ctx.getUserId());
RRateLimiter userRL =
redissonClient.getRateLimiter(
Constants.RATE_LIMIT_GLOBAL_USER_PREFIX + Ctx.getUserId());
boolean acquire2 = userRL.tryAcquire(1);
if (!acquire2) {
sysLogService.saveSysLog(request, "限流模块", "用户限流", "");
writeResponse(new BizException("当前用户请求被限流,请稍后再试"), response);
log.warn("用户限流: sessionId {} user {} request {}", sessionId, Ctx.currentUser().getUsername(), request.getRequestURI());
log.warn(
"用户限流: sessionId {} user {} request {}",
sessionId,
Ctx.currentUser().getUsername(),
request.getRequestURI());
return;
}
}else {
} else {
RRateLimiter rateLimiter = redissonClient.getRateLimiter("global-iprl-" + ip);
rateLimiter.trySetRate(
@@ -88,17 +103,17 @@ public class RateLimitFilter extends OncePerRequestFilter {
Integer.parseInt(
sysConfigService.getConfigVal(
Constants.SYSCONFIG_SESSION_GLOBAL_RATE_LIMIT_PER_MIN)),
1, RateIntervalUnit.MINUTES);
1,
RateIntervalUnit.MINUTES);
boolean acquire = rateLimiter.tryAcquire(1);
if (!acquire) {
sysLogService.saveSysLog(request, "限流模块", "IP限流", "");
writeResponse(new BizException("请求被限流,请稍后再试"), response);
log.warn("ip {} request {} is rate limited", ip, request.getRequestURI());
return;
}
}
filterChain.doFilter(request, response);

View File

@@ -3,7 +3,10 @@ package cn.lihongjie.coal.filter;
import cn.lihongjie.coal.common.Constants;
import cn.lihongjie.coal.common.RequestUtils;
import cn.lihongjie.coal.exception.BizException;
import cn.lihongjie.coal.ip.IpQueryService;
import cn.lihongjie.coal.loginUser.service.LoginUserService;
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
import cn.lihongjie.coal.syslog.service.SysLogService;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -40,6 +43,10 @@ public class SignFilter extends OncePerRequestFilter {
@Autowired ObjectMapper objectMapper;
@Autowired SysConfigService sysConfigService;
@Autowired SysLogService sysLogService;
@Autowired IpQueryService ipQueryService;
@Autowired LoginUserService loginUserService;
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -120,6 +127,7 @@ public class SignFilter extends OncePerRequestFilter {
if (!sign.equals(clientSign)) {
log.debug("key: {} \ndata:{}", token, sb);
log.warn("签名错误: {} {}", clientSign, sign);
sysLogService.saveSysLog(request, "签名模块", "签名错误", clientSign + " " + sign);
RequestUtils.writeResponse(
new BizException(Constants.HTTP_HEADER_CLIENT_SIGN + " 请求头签名错误"), response);
return;
@@ -128,4 +136,7 @@ public class SignFilter extends OncePerRequestFilter {
doFilter(request, response, filterChain);
}
}

View File

@@ -3,6 +3,12 @@ package cn.lihongjie.coal.syslog.service;
import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.base.dto.IdRequest;
import cn.lihongjie.coal.base.service.BaseService;
import cn.lihongjie.coal.common.Constants;
import cn.lihongjie.coal.common.Ctx;
import cn.lihongjie.coal.common.RequestUtils;
import cn.lihongjie.coal.ip.IpQueryService;
import cn.lihongjie.coal.loginUser.dto.LoginUserDto;
import cn.lihongjie.coal.loginUser.service.LoginUserService;
import cn.lihongjie.coal.syslog.dto.CreateSysLogDto;
import cn.lihongjie.coal.syslog.dto.SysLogDto;
import cn.lihongjie.coal.syslog.dto.UpdateSysLogDto;
@@ -11,9 +17,11 @@ import cn.lihongjie.coal.syslog.mapper.SysLogMapper;
import cn.lihongjie.coal.syslog.repository.SysLogRepository;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
@@ -84,4 +92,40 @@ class SysLogService extends BaseService<SysLogEntity, SysLogRepository> {
return page.map(this.mapper::toDto);
}
@Autowired IpQueryService ipQueryService;
@Autowired LoginUserService loginUserService;
public void saveSysLog(
HttpServletRequest request, String module, String action, String message) {
String sessionId = request.getHeader(Constants.HTTP_HEADER_TOKEN);
SysLogEntity sysLogEntity = new SysLogEntity();
sysLogEntity.setIp(RequestUtils.getIp(request));
sysLogEntity.setModule(module);
sysLogEntity.setAction(action);
sysLogEntity.setMessage(message);
sysLogEntity.setIpLocation(ipQueryService.query(sysLogEntity.getIp()));
sysLogEntity.setUserAgent(RequestUtils.getUa(request));
sysLogEntity.setTimeCost(0);
sysLogEntity.setUrl(request.getRequestURI());
sysLogEntity.setOptStatus("1");
if (StringUtils.isNotEmpty(sessionId)) {
try {
LoginUserDto dto = loginUserService.getFromCache(sessionId);
sysLogEntity.setCreateUserId(dto.getUser().getId());
sysLogEntity.setOrganizationId(dto.getUser().getOrganizationId());
} catch (Exception e) {
log.warn("获取用户信息失败", e);
}
}
Ctx.getContext().getBean(this.getClass()).saveSync(sysLogEntity);
}
}