系统同一ip访问限制
This commit is contained in:
parent
228569c461
commit
a0bda3d08e
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -34,3 +34,4 @@ build/
|
||||||
|
|
||||||
### VS Code ###
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
*.log
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.rzyc.advice;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.common.utils.model.MultiResult;
|
import com.common.utils.model.MultiResult;
|
||||||
import com.common.utils.model.SingleResult;
|
import com.common.utils.model.SingleResult;
|
||||||
|
import com.rzyc.utils.IpUtil;
|
||||||
import org.apache.commons.collections.map.HashedMap;
|
import org.apache.commons.collections.map.HashedMap;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
|
@ -40,7 +41,7 @@ public class InterceptAspect {
|
||||||
|
|
||||||
String url = request.getRequestURL().toString();
|
String url = request.getRequestURL().toString();
|
||||||
System.out.println("url - - - - - - - > "+url);
|
System.out.println("url - - - - - - - > "+url);
|
||||||
System.out.println("ip -> "+request.getRemoteAddr());
|
System.out.println("ip -> "+ IpUtil.getIpAddr(request));
|
||||||
|
|
||||||
Map<String,Object> requestMsg = new HashMap<>();
|
Map<String,Object> requestMsg = new HashMap<>();
|
||||||
Map<String,String[]> paramsMap = request.getParameterMap();
|
Map<String,String[]> paramsMap = request.getParameterMap();
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package com.rzyc.advice;
|
||||||
|
|
||||||
import com.common.utils.StringUtils;
|
import com.common.utils.StringUtils;
|
||||||
import com.common.utils.jwt.JwtUtil;
|
import com.common.utils.jwt.JwtUtil;
|
||||||
|
import com.rzyc.advice.exception.TokenException;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.rzyc.advice.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ip限制异常
|
||||||
|
* @author dong
|
||||||
|
* @date 2023-11-22 14:45
|
||||||
|
* @Version V1.0
|
||||||
|
*/
|
||||||
|
public class AccessException extends RuntimeException{
|
||||||
|
|
||||||
|
public AccessException() {
|
||||||
|
super();
|
||||||
|
// TODO 自动生成的构造函数存根
|
||||||
|
}
|
||||||
|
public AccessException(String message) {
|
||||||
|
super(message);
|
||||||
|
// System.out.println(message);
|
||||||
|
// TODO 自动生成的构造函数存根
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.rzyc.advice;
|
package com.rzyc.advice.exception;
|
||||||
|
|
||||||
import com.common.utils.model.Code;
|
import com.common.utils.model.Code;
|
||||||
import com.common.utils.model.Message;
|
import com.common.utils.model.Message;
|
||||||
|
|
@ -127,7 +127,7 @@ public class ExceptionAdvice {
|
||||||
* token授权处理
|
* token授权处理
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ExceptionHandler(com.rzyc.advice.TokenException.class)
|
@ExceptionHandler(TokenException.class)
|
||||||
public SingleResult<String> handleTokenException(Exception e){
|
public SingleResult<String> handleTokenException(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.info("TokenException message -> "+e.getMessage());
|
logger.info("TokenException message -> "+e.getMessage());
|
||||||
|
|
@ -137,6 +137,20 @@ public class ExceptionAdvice {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ip访问限制
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(AccessException.class)
|
||||||
|
public SingleResult<String> handleAccessException(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
logger.info("TokenException message -> "+e.getMessage());
|
||||||
|
SingleResult<String> result = new SingleResult<>();
|
||||||
|
result.setCode(Code.ERROR.getCode());
|
||||||
|
result.setMessage(e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通一异常处理
|
* 通一异常处理
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.rzyc.advice;
|
package com.rzyc.advice.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* token exception
|
* token exception
|
||||||
|
|
@ -1,23 +1,30 @@
|
||||||
package com.rzyc.advice.log;
|
package com.rzyc.advice.log;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.common.utils.RandomNumber;
|
import com.common.utils.RandomNumber;
|
||||||
import com.common.utils.StringUtils;
|
import com.common.utils.StringUtils;
|
||||||
import com.common.utils.jwt.JwtUtil;
|
import com.common.utils.jwt.JwtUtil;
|
||||||
import com.common.utils.model.Result;
|
import com.common.utils.model.Result;
|
||||||
|
import com.rzyc.advice.exception.AccessException;
|
||||||
|
import com.rzyc.config.RedisUtil;
|
||||||
import com.rzyc.mapper.log.SysLogsMapper;
|
import com.rzyc.mapper.log.SysLogsMapper;
|
||||||
import com.rzyc.mapper.user.SysUserMapper;
|
import com.rzyc.mapper.user.SysUserMapper;
|
||||||
import com.rzyc.model.user.SysUser;
|
import com.rzyc.model.user.SysUser;
|
||||||
import com.rzyc.model.log.SysLogsWithBLOBs;
|
import com.rzyc.model.log.SysLogsWithBLOBs;
|
||||||
|
import com.rzyc.utils.IpUtil;
|
||||||
import org.apache.commons.collections.map.HashedMap;
|
import org.apache.commons.collections.map.HashedMap;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
@ -26,6 +33,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志记录
|
* 日志记录
|
||||||
|
|
@ -45,6 +53,21 @@ public class LogAspect {
|
||||||
@Autowired
|
@Autowired
|
||||||
protected SysUserMapper sysUserMapper;
|
protected SysUserMapper sysUserMapper;
|
||||||
|
|
||||||
|
|
||||||
|
//单位时间内最大访问数
|
||||||
|
private static final Integer MAX_COUNT = 20;
|
||||||
|
|
||||||
|
//单位时间
|
||||||
|
private static final Integer UNIT_TIME = 1 * 1000;
|
||||||
|
|
||||||
|
//限制时长
|
||||||
|
private static final Long REJECT_TIME = 10 * 60 * 1000L;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
|
private ApplicationContext context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拦截位置
|
* 拦截位置
|
||||||
*/
|
*/
|
||||||
|
|
@ -57,14 +80,28 @@ public class LogAspect {
|
||||||
|
|
||||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
|
||||||
.getRequestAttributes()).getRequest();
|
.getRequestAttributes()).getRequest();
|
||||||
|
|
||||||
|
String ip = IpUtil.getIpAddr(request);
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
System.out.println("uri -> "+ request.getRequestURI());
|
System.out.println("uri -> "+ request.getRequestURI());
|
||||||
System.out.println("ip -> "+request.getRemoteAddr());
|
System.out.println("ip -> "+ip);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 先判断ip访问是否超过限制 在记录日志
|
||||||
|
* @version v1.0
|
||||||
|
* @author dong
|
||||||
|
* @date 2023/11/22 14:57
|
||||||
|
*/
|
||||||
|
//判断ip访问数量
|
||||||
|
assessIp(ip);
|
||||||
|
|
||||||
|
|
||||||
Map<String,Object> requestMsg = new HashMap<>();
|
Map<String,Object> requestMsg = new HashMap<>();
|
||||||
|
|
||||||
String queryString = request.getQueryString();
|
String queryString = request.getQueryString();
|
||||||
System.out.println("queryString -> "+queryString);
|
System.out.println("queryString -> "+queryString);
|
||||||
// System.out.println("joinPoint -> "+JSONArray.toJSONString(joinPoint.getArgs()));
|
|
||||||
|
|
||||||
|
|
||||||
//获取存在header中的用户token
|
//获取存在header中的用户token
|
||||||
|
|
@ -113,7 +150,7 @@ public class LogAspect {
|
||||||
logs.setUserId(userId);
|
logs.setUserId(userId);
|
||||||
logs.setParams(JSONArray.toJSONString(requestMsg));
|
logs.setParams(JSONArray.toJSONString(requestMsg));
|
||||||
logs.setResponseStr(JSONArray.toJSONString(responseMap));
|
logs.setResponseStr(JSONArray.toJSONString(responseMap));
|
||||||
logs.setIpAddress(request.getRemoteAddr());
|
logs.setIpAddress(ip);
|
||||||
logs.setUrl(request.getRequestURI());
|
logs.setUrl(request.getRequestURI());
|
||||||
saveLog saveLog = new saveLog(logs);
|
saveLog saveLog = new saveLog(logs);
|
||||||
Thread thread = new Thread(saveLog);
|
Thread thread = new Thread(saveLog);
|
||||||
|
|
@ -122,6 +159,51 @@ public class LogAspect {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过ip判断访问数量限制
|
||||||
|
* @version v1.0
|
||||||
|
* @author dong
|
||||||
|
* @date 2023/11/22 14:58
|
||||||
|
*/
|
||||||
|
private void assessIp(String ip)throws Exception{
|
||||||
|
//过滤黑名单
|
||||||
|
if (redisUtil.hasKey("filter:ip:black:" + ip)) {
|
||||||
|
System.out.println("ip访问过于频繁,已被限制=>" + ip + " 倒计时" + redisUtil.getExpire("filter:ip:black:" + ip));
|
||||||
|
throw new AccessException("访问过于频繁,请稍后重试");
|
||||||
|
}
|
||||||
|
//判断ip是否首次访问
|
||||||
|
if (redisUtil.hExists("filter:ip:normal", "count:" + ip)) {
|
||||||
|
//判断最大访问次数
|
||||||
|
Integer maxCount = Integer.valueOf(redisUtil.hGet("filter:ip:normal", "count:" + ip).toString());
|
||||||
|
System.out.println("ip:" + ip + " 访问" + maxCount + "次");
|
||||||
|
if (maxCount > MAX_COUNT) {
|
||||||
|
Long maxTime = Long.valueOf(redisUtil.hGet("filter:ip:normal", "time:" + ip).toString());
|
||||||
|
if (System.currentTimeMillis() - maxTime < UNIT_TIME) {
|
||||||
|
System.out.println("ip访问过于频繁,已被限制=>" + ip + " 倒计时" + REJECT_TIME);
|
||||||
|
redisUtil.setEx("filter:ip:black:" + ip, "1", REJECT_TIME, TimeUnit.MILLISECONDS);
|
||||||
|
String str[] = {"count:" + ip, "time:" + ip};
|
||||||
|
redisUtil.hDelete("filter:ip:normal", str);
|
||||||
|
throw new AccessException("访问过于频繁,请稍后重试");
|
||||||
|
}
|
||||||
|
initVisitsIP(ip);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("--------->initVisitsIP");
|
||||||
|
initVisitsIP(ip);
|
||||||
|
}
|
||||||
|
redisUtil.hIncrBy("filter:ip:normal", "count:" + ip, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化访问ip
|
||||||
|
* @param ip
|
||||||
|
*/
|
||||||
|
private void initVisitsIP(String ip) {
|
||||||
|
redisUtil.hPut("filter:ip:normal", "count:" + ip, "0");
|
||||||
|
redisUtil.hPut("filter:ip:normal", "time:" + ip, String.valueOf(System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步保存日志
|
* 异步保存日志
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.rzyc.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
|
@ -17,6 +18,95 @@ public class RedisUtil {
|
||||||
@Autowired
|
@Autowired
|
||||||
RedisTemplate<String,Object> redisTemplate;
|
RedisTemplate<String,Object> redisTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate redisTemp;
|
||||||
|
|
||||||
|
public void setRedisTemplate(StringRedisTemplate redisTemp) {
|
||||||
|
this.redisTemp = redisTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看哈希表 key 中,指定的字段是否存在
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param field
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean hExists(String key, String field) {
|
||||||
|
return redisTemp.opsForHash().hasKey(key, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存储在哈希表中指定字段的值
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param field
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Object hGet(String key, String field) {
|
||||||
|
return redisTemp.opsForHash().get(key, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将值 value 关联到 key ,并将 key 的过期时间设为 timeout
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
* @param timeout 过期时间
|
||||||
|
* @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES
|
||||||
|
* 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
|
||||||
|
*/
|
||||||
|
public void setEx(String key, String value, long timeout, TimeUnit unit) {
|
||||||
|
redisTemp.opsForValue().set(key, value, timeout, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除一个或多个哈希表字段
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param fields
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Long hDelete(String key, Object... fields) {
|
||||||
|
return redisTemp.opsForHash().delete(key, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为哈希表 key 中的指定字段的整数值加上增量 increment
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param field
|
||||||
|
* @param increment
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Long hIncrBy(String key, Object field, long increment) {
|
||||||
|
return redisTemp.opsForHash().increment(key, field, increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入数据
|
||||||
|
* @version v1.0
|
||||||
|
* @author dong
|
||||||
|
* @date 2023/11/22 14:04
|
||||||
|
*/
|
||||||
|
public void hPut(String key, String hashKey, String value) {
|
||||||
|
redisTemp.opsForHash().put(key, hashKey, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在key
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Boolean hasKey(String key) {
|
||||||
|
return redisTemp.hasKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get 多参数分隔 :
|
* get 多参数分隔 :
|
||||||
* @param key 键
|
* @param key 键
|
||||||
|
|
@ -63,19 +153,6 @@ public class RedisUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断key是否存在
|
|
||||||
* @param key 键
|
|
||||||
* @return true 存在 false不存在
|
|
||||||
*/
|
|
||||||
public boolean hasKey(String key) {
|
|
||||||
try {
|
|
||||||
return redisTemplate.hasKey(key);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
119
inventory-gov/src/main/java/com/rzyc/filter/IpFilter.java
Normal file
119
inventory-gov/src/main/java/com/rzyc/filter/IpFilter.java
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.rzyc.filter;
|
||||||
|
|
||||||
|
import com.rzyc.config.RedisUtil;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||||
|
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.annotation.WebFilter;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dong
|
||||||
|
* @date 2023-11-22 13:55
|
||||||
|
* @Version V1.0
|
||||||
|
*/
|
||||||
|
//@Order(0)
|
||||||
|
//@Component
|
||||||
|
//@WebFilter(filterName = "IPFilter", urlPatterns = "/*")
|
||||||
|
public class IpFilter implements Filter {
|
||||||
|
|
||||||
|
|
||||||
|
//单位时间内最大访问数
|
||||||
|
private static final Integer MAX_COUNT = 15;
|
||||||
|
|
||||||
|
//单位时间
|
||||||
|
private static final Integer UNIT_TIME = 1 * 1000;
|
||||||
|
|
||||||
|
//限制时长
|
||||||
|
private static final Long REJECT_TIME = 10 * 60 * 1000L;
|
||||||
|
|
||||||
|
private static RedisUtil redisUtil;
|
||||||
|
|
||||||
|
private ApplicationContext context;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
context = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
|
||||||
|
if (redisUtil == null) {
|
||||||
|
redisUtil = new RedisUtil();
|
||||||
|
StringRedisTemplate redisTemplate = (StringRedisTemplate) context.getBean("stringRedisTemplate");
|
||||||
|
redisUtil.setRedisTemplate(redisTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
String ip = request.getRemoteAddr();
|
||||||
|
//过滤黑名单
|
||||||
|
if (redisUtil.hasKey("filter:ip:black:" + ip)) {
|
||||||
|
System.out.println("ip访问过于频繁,已被限制=>" + ip + " 倒计时" + redisUtil.getExpire("filter:ip:black:" + ip));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//判断ip是否首次访问
|
||||||
|
if (redisUtil.hExists("filter:ip:normal", "count:" + ip)) {
|
||||||
|
//判断最大访问次数
|
||||||
|
Integer maxCount = Integer.valueOf(redisUtil.hGet("filter:ip:normal", "count:" + ip).toString());
|
||||||
|
System.out.println("ip:" + ip + " 访问" + maxCount + "次");
|
||||||
|
if (maxCount > MAX_COUNT) {
|
||||||
|
Long maxTime = Long.valueOf(redisUtil.hGet("filter:ip:normal", "time:" + ip).toString());
|
||||||
|
if (System.currentTimeMillis() - maxTime < UNIT_TIME) {
|
||||||
|
System.out.println("ip访问过于频繁,已被限制=>" + ip + " 倒计时" + REJECT_TIME);
|
||||||
|
redisUtil.setEx("filter:ip:black:" + ip, "1", REJECT_TIME, TimeUnit.MILLISECONDS);
|
||||||
|
String str[] = {"count:" + ip, "time:" + ip};
|
||||||
|
redisUtil.hDelete("filter:ip:normal", str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
initVisitsIP(ip);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initVisitsIP(ip);
|
||||||
|
}
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
redisUtil.hIncrBy("filter:ip:normal", "count:" + ip, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化访问ip
|
||||||
|
* @param ip
|
||||||
|
*/
|
||||||
|
private void initVisitsIP(String ip) {
|
||||||
|
redisUtil.hPut("filter:ip:normal", "count:" + ip, "0");
|
||||||
|
redisUtil.hPut("filter:ip:normal", "time:" + ip, String.valueOf(System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取真实ip
|
||||||
|
* @author: hanguodong
|
||||||
|
* @date: 2023/6/6 22:12
|
||||||
|
* @param: [request]
|
||||||
|
* @return:
|
||||||
|
**/
|
||||||
|
public String getIpAddr(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader("X-Real-IP");
|
||||||
|
if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
ip = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
int index = ip.indexOf(',');
|
||||||
|
if (index != -1) {
|
||||||
|
return ip.substring(0, index);
|
||||||
|
} else {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import com.common.utils.jwt.JwtUtil;
|
||||||
import com.rzyc.advice.CustomException;
|
import com.rzyc.advice.CustomException;
|
||||||
import com.rzyc.mapper.AuthorityKeyMapper;
|
import com.rzyc.mapper.AuthorityKeyMapper;
|
||||||
import com.rzyc.model.AuthorityKey;
|
import com.rzyc.model.AuthorityKey;
|
||||||
|
import com.rzyc.utils.IpUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
|
@ -40,7 +41,8 @@ public class JwtAuthenticationTokenFiler extends OncePerRequestFilter {
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
//获取token
|
//获取token
|
||||||
String token = request.getHeader("userToken");
|
String token = request.getHeader("userToken");
|
||||||
System.out.println("addr ------> "+request.getLocalAddr());
|
|
||||||
|
System.out.println("addr ------> "+ IpUtil.getIpAddr(request));
|
||||||
/* if (!StringUtils.hasText(token)) {
|
/* if (!StringUtils.hasText(token)) {
|
||||||
//放行
|
//放行
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
|
|
|
||||||
37
inventory-gov/src/main/java/com/rzyc/utils/IpUtil.java
Normal file
37
inventory-gov/src/main/java/com/rzyc/utils/IpUtil.java
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.rzyc.utils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dong
|
||||||
|
* @date 2023-11-22 14:32
|
||||||
|
* @Version V1.0
|
||||||
|
*/
|
||||||
|
public class IpUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取真实ip
|
||||||
|
* @author: hanguodong
|
||||||
|
* @date: 2023/6/6 22:12
|
||||||
|
* @param: [request]
|
||||||
|
* @return:
|
||||||
|
**/
|
||||||
|
public static String getIpAddr(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader("X-Real-IP");
|
||||||
|
if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
ip = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
int index = ip.indexOf(',');
|
||||||
|
if (index != -1) {
|
||||||
|
return ip.substring(0, index);
|
||||||
|
} else {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package com.rzyc.utils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* redis 方法
|
|
||||||
* @author dong
|
|
||||||
* @date 2023-11-22 10:53
|
|
||||||
* @Version V1.0
|
|
||||||
*/
|
|
||||||
public class RedisUtil {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
System.out.println("");
|
|
||||||
System.out.println("");
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,17 @@ server:
|
||||||
port: 7010
|
port: 7010
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
|
redis:
|
||||||
|
host: 42.193.40.239
|
||||||
|
password: zysoft2023@com
|
||||||
|
port: 6937
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 8
|
||||||
|
max-idle: 8
|
||||||
|
min-idle: 0
|
||||||
|
max-wait: 100
|
||||||
|
shutdown-timeout: 50000
|
||||||
servlet:
|
servlet:
|
||||||
multipart:
|
multipart:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
@ -59,9 +70,9 @@ logging:
|
||||||
#文件上传的配置
|
#文件上传的配置
|
||||||
onstants:
|
onstants:
|
||||||
#上传文件存放地址
|
#上传文件存放地址
|
||||||
file_location: /static/resource/inventory/uploadFile/
|
file_location: C:/mnt/resource/inventory/uploadFile/
|
||||||
#上传文件公共地址
|
#上传文件公共地址
|
||||||
file_header: /static/resource/inventory/uploadFile/
|
file_header: /resource/inventory/uploadFile/
|
||||||
#上传文件基础路径
|
#上传文件基础路径
|
||||||
service_file_header: http://172.27.181.247:8010/
|
service_file_header: http://172.27.181.247:8010/
|
||||||
#父级地区id
|
#父级地区id
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user