All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.zhyd.braum.spring.boot.BraumShieldProcessor Maven / Gradle / Ivy

package me.zhyd.braum.spring.boot;

import me.zhyd.braum.spring.boot.cache.Cache;
import me.zhyd.braum.spring.boot.cache.CacheObj;
import me.zhyd.braum.spring.boot.property.BraumProperties;
import me.zhyd.braum.spring.boot.utils.GlobalBraumUtil;
import me.zhyd.braum.spring.boot.utils.RequestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * 布隆之盾,主管防御
 *
 * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
 * @version 1.0
 * @since 1.8
 */
public class BraumShieldProcessor implements BraumProcessor {
    private static final Logger log = LoggerFactory.getLogger(BraumShieldProcessor.class);

    @Autowired
    private BraumProperties properties;
    @Autowired
    @Qualifier("braumCache")
    private Cache cache;

    /**
     * 布隆之盾出击
     *
     * @return BraumResponse
     */
    @Override
    public BraumResponse process(HttpServletRequest request) {
        RequestUtil requestUtil = new RequestUtil(request);
        String ip = requestUtil.getIp();
        String key = GlobalBraumUtil.INSTANCE.formatKey(ip);
        String lockKey = GlobalBraumUtil.INSTANCE.getLockKey(key);
        String lockMsgTpl = "[%s]涉嫌恶意访问已被临时限制!共被限制过[%s]次,本次剩余限制时间:%s ms",
                accessMsgTpl = "[%s]在%s毫秒内已连续发起 %s 次请求";

        int blocklistCount = 0;
        boolean isBlockingAccess = (properties.getFaultTolerance() != -1 && (blocklistCount = this.getBlacklistCount(key)) > properties.getFaultTolerance());
        if (isBlockingAccess) {
            return new BraumResponse().isError()
                    .setMsg("Access has been restricted!")
                    .setExpire(-1)
                    .setLimitCount(blocklistCount)
                    .setAccessInfo(request);
        }
        // 本次被限制访问
        if (cache.hasKey(lockKey)) {
            blocklistCount = this.getBlacklistCount(key);
            long expire = cache.getExpire(lockKey);
            String msg = String.format(lockMsgTpl, ip, blocklistCount, expire);
            log.debug(msg);
            return new BraumResponse().isError()
                    .setMsg(msg)
                    .setExpire(expire)
                    .setLimitCount(blocklistCount)
                    .setAccessInfo(request);
        }

        // 再次被限制访问
        if (isLimitedAccess(key)) {
            this.save2Blacklist(key);
            cache.set(lockKey, 1, properties.getLimitedTime(), TimeUnit.MILLISECONDS);
            long expire = cache.getExpire(lockKey);
            blocklistCount = this.getBlacklistCount(key);
            String msg = String.format(lockMsgTpl, ip, blocklistCount, expire);
            return new BraumResponse().isError()
                    .setMsg(msg)
                    .setExpire(expire)
                    .setLimitCount(blocklistCount)
                    .setAccessInfo(request);
        }

        String msg = String.format(accessMsgTpl, ip, properties.getInterval(), cache.get(key).getValue());
        return new BraumResponse()
                .isSuccess()
                .setMsg(msg)
                .setAccessInfo(request);
    }

    /**
     * 拉黑用户
     *
     * @param ip 当前发起请求的用户IP
     */
    private void save2Blacklist(String ip) {
        String blacklistKey = GlobalBraumUtil.INSTANCE.getBlacklistKey(ip);
        cache.set(blacklistKey, getBlacklistCount(ip) + 1, properties.getBlacklistTime(), TimeUnit.MILLISECONDS);
    }

    /**
     * 获取被拉黑过的次数
     *
     * @param ip 当前发起请求的用户IP
     */
    private int getBlacklistCount(String ip) {
        String blacklistKey = GlobalBraumUtil.INSTANCE.getBlacklistKey(ip);
        CacheObj blacklistCache = cache.get(blacklistKey);
        if (null == blacklistCache) {
            return 0;
        }
        return blacklistCache.getValue();
    }

    /**
     * 是否已经被限制访问
     *
     * @param ip 当前发起请求的用户IP
     */
    private boolean isLimitedAccess(String ip) {
        return cache.incrementAndGet(ip) > properties.getThreshold();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy