博客系统添加IP黑名单拦截功能

    为博客系统添加IP黑名单拦截功能 
          仅贴出部分代码

创建IP拦截器

package com.my.blog.website.interceptor;
import com.my.blog.website.service.ILogService;
import com.my.blog.website.utils.IpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Jesse-liu
 * @description: Ip黑名单拦截器
 * @date 2020/5/13 11:12
 */
@Component
public class IpInterceptor implements HandlerInterceptor {

    @Resource
    private ILogService logService;

    private static final Logger LOGGE = LoggerFactory.getLogger(IpInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        LOGGE.info("进入IP黑名单拦截器:{}", IpUtils.getIpAddress(request));
        String ip = IpUtils.getIpAddress(request);
        if (IpUtils.chickIpBreak(ip)) {
            logService.insertLog("进入IP黑名单拦截器", IpUtils.getIpAddress(request), request.getRemoteAddr(), null);
            response.setHeader("Content-Type", "text/html; charset=UTF-8");
            response.getWriter().write("<p>欢迎使用.</p>");
            response.getWriter().flush();
            response.getWriter().close();
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

}

往webMVC里添加拦截器组件

   仅贴出部分代码:
package com.my.blog.website.interceptor;
import com.my.blog.website.utils.TaleUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

/**
 * 向mvc中添加自定义组件
 * Created by BlueT on 2017/3/9.
 * 更换MVC配置类
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Resource
    private BaseInterceptor baseInterceptor;
    @Resource
    private IpInterceptor ipInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       //拦截器是按顺序执行的
        registry.addInterceptor(ipInterceptor);
        registry.addInterceptor(baseInterceptor);
    }
}

使用的工具类

package com.my.blog.website.utils;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;

/**
 * @author Jesse-liu
 * @description: ip操作工具类
 * @date 2020/5/13 11:29
 */
public class IpUtils {

    private static String longToIp(Long number) {
        String ip = "";
        for (int i = 3; i >= 0; i--) {
            long tmp = number >> (8 * i);
            ip += String.valueOf((tmp & 0xff));
            if (i != 0) {
                ip += ".";
            }
        }
        return ip;
    }

    private static Long ipToLong(String ip) {
        long ips = 0l;
        String[] ipArr = ip.split("\\.");
        for (int i = 0; i < 4; i++) {
            ips = ips << 8 | Integer.parseInt(ipArr[i]);
        }
        return ips;
    }

    private static String date;
    private static PropertiesUtil p = null;

    /***
     * 校验IP是否加入黑名单
     * @param ip
     * @return true 是在黑名单
     * @throws IOException
     */
    public static boolean chickIpBreak(String ip) throws IOException {
        if (p == null) {
            p = new PropertiesUtil("ip-black.properties");
        } else {
            String str = new SimpleDateFormat("MMddHHmmss").format(new Date());
            str = str.substring(0, 9);
            if (date == null || !date.equals(str)) {
                date = str;
                p = new PropertiesUtil("ip-black.properties");
            }
        }
        Enumeration en = p.getProps().propertyNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            if (StringUtils.isNotBlank(key) && key.contains("~")) {
                String[] ipTemps = key.split("~");
                if (!isLocalIp(ip) && (Long.parseLong(ipTemps[0]) <= IpUtils.ipToLong(ip) &&
                        IpUtils.ipToLong(ip) <= Long.parseLong(ipTemps[1]))) {
                    return true;
                }

            } else if (!isLocalIp(ip) && key.equals(IpUtils.ipToLong(ip).toString())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
     *
     * @param request
     * @return
     * @throws IOException
     */
    public final static String getIpAddress(HttpServletRequest request)
            throws IOException {
        // 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址

        String ip = request.getHeader("X-Forwarded-For");
        // if (logger.isInfoEnabled()) {
        // logger.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip="
        // + ip);
        // }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
                // if (logger.isInfoEnabled()) {
                // logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip="
                // + ip);
                // }
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
                // if (logger.isInfoEnabled()) {
                // logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip="
                // + ip);
                // }
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
                // if (logger.isInfoEnabled()) {
                // logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip="
                // + ip);
                // }
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                // if (logger.isInfoEnabled()) {
                // logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip="
                // + ip);
                // }
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                // if (logger.isInfoEnabled()) {
                // logger.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip="
                // + ip);
                // }
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }

        return ip;
    }

    /***
     * 服务器是否是本机ip
     * @param ip
     * @return
     */
    public static boolean isLocalIp(String ip) throws IOException {
        return ip.equals("127.0.0.1") || ip.equals("localhost") || ip.equals("0:0:0:0:0:0:0:1");
    }
}
package com.my.blog.website.utils;

import java.io.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author Jesse-liu
 * @description: 配置文件读取工具类
 * @date 2020/5/13 11:24
 */
public class PropertiesUtil {
    //配置文件的路径
    private String configPath = null;

    /**
     * 配置文件对象
     */
    private Properties props = null;

    public PropertiesUtil() throws IOException {
        if (props == null) {
            InputStreamReader in = new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream("ip-black.properties"), "utf-8");
            props = new Properties();
            props.load(in);
            //关闭资源
            in.close();
        }
    }

    /**
     * @param path 配置文件路径
     * @return : null
     * @author Jesse-liu
     * @date 2020/5/13
     * @description: 有参构造函数,用于sh运行,自动找到classpath下的path路径。
     **/
    public PropertiesUtil(String path) throws IOException {
        if (props == null) {
            InputStreamReader in = new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(path), "utf-8");
            configPath = path;
            props = new Properties();
            props.load(in);
            //关闭资源
            in.close();
        }
    }

    /**
     * 根据key值读取配置的值
     * Jun 26, 2010 9:15:43 PM
     *
     * @param key key值
     * @return key 键对应的值
     * @throws IOException
     * @author 朱志杰
     */
    public String readValue(String key) throws IOException {
        return props.getProperty(key);
    }

    /**
     * 读取properties的全部信息
     *
     * @throws FileNotFoundException 配置文件没有找到
     * @throws IOException           关闭资源文件,或者加载配置文件错误
     */
    public Map<String, String> readAllProperties() throws FileNotFoundException, IOException {
        //保存所有的键值
        Map<String, String> map = new HashMap<String, String>();
        Enumeration en = props.propertyNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            String value = props.getProperty(key);
            map.put(key, value);
        }
        return map;
    }

    private static String longToIp(Long number) {
        String ip = "";
        for (int i = 3; i >= 0; i--) {
            long tmp = number >> (8 * i);
            ip += String.valueOf((tmp & 0xff));
            if (i != 0) {
                ip += ".";
            }
        }
        return ip;
    }

    /**
     * 设置某个key的值,并保存至文件。
     * by https://blog.csdn.net/qq_40147276/article/details/91976753
     *
     * @param key key值
     * @return key 键对应的值
     * @throws IOException
     */
    public void setValue(String key, String value) throws IOException {
        Properties prop = new Properties();
        InputStreamReader fis = new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(this.configPath), "utf-8");
        // 从输入流中读取属性列表(键和元素对)
        prop.load(fis);
        // 调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。
        // 强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("ip-black.properties"), "utf-8");
        prop.setProperty(key, value);
        // 以适合使用 load 方法加载到 Properties 表中的格式,
        // 将此 Properties 表中的属性列表(键和元素对)写入输出流
        prop.store(writer, "last update");
        //关闭文件
        fis.close();
        writer.close();
    }

    /**
     * @return the props
     */
    public Properties getProps() {
        return props;
    }
}

导语

创建一个 ip-black.properties 放在 resources 目录下

# ip黑名单设置  需要把IP转成Long类型
236000768~236001023