ip频繁调用接口过滤设置黑名单

针对某个IP频繁恶意调用API接口,将ip设置成黑名单
  1. 代码如下(可以在拦截中添加)
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.*;

/**
 * 接口ip防刷
 * Created by mayn on 2019/1/15.
 */
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();
        //int index = 0;
        for (Map.Entry<Long,Double> m:entries){
            //index++;
            if(val<=m.getKey()){
                /**计算每秒多少次*/
                ind = m.getValue();
                break;
            }
            //if(index==rule.size()&&(ind==0||ind.equals(0))){
                /**计算每秒多少次*/
                //ind = (val*m.getValue())/1000;
            //}
        }
        if(count>=ind&&ind>0){
            return false;
        }
        return true;
    }
    /**
     * 获取拦截规则
     * @param
     * @author huanglj
     * @return java.util.Map<java.lang.Long,java.lang.Double>
     * @createTime 2019/1/15 15:42
     * @version v1.0
     */
    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;
    }

    /**
     * ture:通过,false:拒绝
     * @author huanglj
     * @return boolean
     * @createTime 2018/9/2 19:16
     * @version v1.0
     */
    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);
        /**判断该ip是否在黑名单内*/
        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;
    }
}

  1. 配置
#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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值