针对某个IP频繁恶意调用API接口,将ip设置成黑名单
- 代码如下(可以在拦截中添加)
package net.dotclouds.rule;
import net.dotclouds.common.Constants;
import net.dotclouds.conf.ChatConf;
import net.dotclouds.config.RedisClient;
import net.dotclouds.util.EncryptionUtil;
import net.dotclouds.util.MapUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.HashOperations;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
public class IpRule {
private final static Logger log = LoggerFactory.getLogger(IpRule.class);
private int count;
private Long start;
private Long end;
private static Object obj = new Object();
private HashOperations<String, Object, Object> opsForHash;
private RedisClient redisClient;
private String companyId;
private static final String START_TIME = "startTime";
private static final String COUNT = "count";
private static final String IP_BLACK = "ipBlack";
public boolean calculationRule(Map<Long, Double> rule){
long val = end-start;
Double ind = 0D;
Set<Map.Entry<Long, Double>> entries = rule.entrySet();
for (Map.Entry<Long,Double> m:entries){
if(val<=m.getKey()){
ind = m.getValue();
break;
}
}
if(count>=ind&&ind>0){
return false;
}
return true;
}
private Map<Long,Double> getRule(){
String[] split = ChatConf.HTTP_IP_BLACK_RULE.split(";");
TreeMap<Long,Double> map = new TreeMap<Long,Double>();
Long key = 0L;
for (String s:split){
String[] val = s.split(",");
key = Long.valueOf(val[0]);
map.put(key*1000,Double.valueOf(val[1]));
}
return map;
}
public boolean rule(HttpServletRequest request,String ipAdrress){
if(null==ChatConf.HTTP_IP_BLACK_RULE
||!"1".equals(ChatConf.HTTP_IP_BLACK_RULE_OPEN))
return true;
Object o = opsForHash.get(companyId + "_" + IP_BLACK, ipAdrress);
if(null!=o){
Long endTime = (Long)o;
if(System.currentTimeMillis()-endTime<(ChatConf.HTTP_IP_BLACK_RULE_LIFE_TIME*1000)){
return false;
} else {
opsForHash.delete(companyId + "_" + IP_BLACK, ipAdrress);
}
}
String url = request.getServletPath();
String key = EncryptionUtil.md5Crypt(ipAdrress+url);
Object val = opsForHash.get(companyId+"_"+Constants.REDIS_LIST_NAME.IP_BLACK_LIST,key);
Map<String,Object> param = null;
if(null==val){
param = new HashMap<String,Object>();
} else {
param = (Map<String,Object>)val;
}
long ipStartTime = 0L;
Object to = param.get(START_TIME);
long now = System.currentTimeMillis();
Map<Long, Double> rule = getRule();
if(null==rule||rule.isEmpty()){
return true;
}
if(null==to){
ipStartTime = now;
param.put(START_TIME,ipStartTime);
} else {
ipStartTime = (Long)to;
Set<Long> longs = rule.keySet();
Iterator<Long> iterator = longs.iterator();
Long next = iterator.next();
if(now-ipStartTime>next){
ipStartTime = now;
param.put(COUNT,0);
}
}
Object count = param.get(COUNT);
Integer index = 1;
if(null!=count){
index += (Integer)count;
}
param.put(COUNT,index);
init(index,ipStartTime,System.currentTimeMillis());
boolean flg = calculationRule(rule);
redisClient.hset(companyId+"_"+Constants.REDIS_LIST_NAME.IP_BLACK_LIST,key,param,10);
if(!flg){
opsForHash.put(companyId + "_" + IP_BLACK,ipAdrress,System.currentTimeMillis());
log.info("===>添加Ip:{}到黑名单",ipAdrress);
}
param.clear();
param = null;
return flg;
}
public void init(int count,Long start,Long end){
this.count = count;
this.start = start;
this.end = end;
}
public String getCompanyId() {
return companyId;
}
public void setCompanyId(String companyId) {
this.companyId = companyId;
}
public HashOperations<String, Object, Object> getOpsForHash() {
return opsForHash;
}
public void setOpsForHash(HashOperations<String, Object, Object> opsForHash) {
this.opsForHash = opsForHash;
}
public RedisClient getRedisClient() {
return redisClient;
}
public void setRedisClient(RedisClient redisClient) {
this.redisClient = redisClient;
}
}
- 配置
#IP黑名单过滤规则
HTTP_IP_BLACK_RULE=1,5
#开启IP过滤
HTTP_IP_BLACK_RULE_OPEN=-1
#黑名单过期时间
HTTP_IP_BLACK_RULE_LIFE_TIME=600
HTTP_IP_BLACK_RULE_PATH=/dotclouds/chat/conversation/createConv;/dotclouds/chat/conversation/test