博客系统添加IP黑名单拦截功能
warning:
这篇文章距离上次修改已过603天,其中的内容可能已经有所变动。
为博客系统添加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