首页 > 编程 > Java > 正文

SpringMVC通过拦截器实现IP黑名单

2019-11-26 08:44:59
字体:
来源:转载
供稿:网友

本文实例为大家分享了SpringMVC通过拦截器实现IP黑名单的具体代码,供大家参考,具体内容如下

以前没有遇到这个需要,后面在网上找了很久,参考了很多文档给出的方案。

1.配置拦截器

这里使用全局拦截:

<mvc:interceptors>  <mvc:interceptor>   <mvc:mapping path="/**"/>   <bean class="com.nps.base.filter.LoginInterceptor"></bean>  </mvc:interceptor></mvc:interceptors>

拦截器LoginInterceptor代码:

package com.nps.base.filter;import java.io.IOException;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import com.nps.utils.IpInterceptUtils; /** * 验证拦截器 * @author HUANG */public class LoginInterceptor implements HandlerInterceptor {private final static Logger logger = LoggerFactory .getLogger(LoginInterceptor.class);@Overridepublic void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {}@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ip = getIpAddress(request); if (IpInterceptUtils.chickIpBreak(ip)) { return false; } Map<String, String> map = getParameterMap(request);// 获取url中的所有参数 String servletUrl = request.getServletPath();// servlet地址 String url = getRealUrl(servletUrl, map); if (url.indexOf("/user/") == 0) { Object user = request.getSession().getAttribute("User"); if (user == null) { // System.out.println("尚未登录,调到登录页面"); response.sendRedirect(request.getContextPath() + "/loginOut.do"); return false; } } return true;}/** * 获取请求主机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;}/** * 根据request获取所有的参数集 *  * @param request * @return */protected Map<String, String> getParameterMap(HttpServletRequest request) { Enumeration<String> names = request.getParameterNames(); String name; Map<String, String> map = new HashMap<String, String>(); while (names.hasMoreElements()) { name = names.nextElement(); map.put(name, request.getParameter(name).trim().replaceAll("'", "")); } return map;}/** * 获取url *  * @param uri * @param params * @return */String getRealUrl(String uri, Map<String, String> params) { StringBuffer sb = new StringBuffer(uri); if (params != null) { int i = 0; for (String key : params.keySet()) { i++; if (i == 1) { sb.append("?" + key + "=" + params.get(key)); } else { sb.append("&" + key + "=" + params.get(key)); } } } return sb.toString();}}

2.校验IP工具

public class IpInterceptUtils {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("conf/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("conf/ip-black.properties");  } }   Enumeration en = p.getProps().propertyNames();   while (en.hasMoreElements()) {    String key = (String) en.nextElement();    if(key.equals(ip)){    return true;    }   } return false; }}

3.配置文件读取类

PropertiesUtil

package com.nps.base.model;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import java.util.Properties;import org.springframework.stereotype.Component;/** * 读取Properties综合类,默认绑定到classpath下的config.properties文件。 * @author  */@Component("PropertiesUtil")public class PropertiesUtil { //配置文件的路径 private String configPath=null;  /**  * 配置文件对象  */ private Properties props=null;  /**  * 默认构造函数,用于sh运行,自动找到classpath下的config.properties。  */ public PropertiesUtil() throws IOException{  if(props==null){  InputStream in = PropertiesUtil.class.getClassLoader().getResourceAsStream("conf/application.properties");   props = new Properties();   props.load(in);    //关闭资源   in.close();  }   }  /**  * 默认构造函数,用于sh运行,自动找到classpath下的config.properties。  */ public PropertiesUtil(String path) throws IOException{  if(props==null){  InputStream in = PropertiesUtil.class.getClassLoader().getResourceAsStream(path);   props = new Properties();   props.load(in);    //关闭资源   in.close();  }   }  /**  * 根据key值读取配置的值  * Jun 26, 2010 9:15:43 PM  * @author 朱志杰  * @param key key值  * @return key 键对应的值   * @throws IOException   */ 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 Property = props.getProperty(key);   map.put(key, Property);  }  return map; } /**  * 设置某个key的值,并保存至文件。  * @param key key值  * @return key 键对应的值   * @throws IOException   */ public void setValue(String key,String value) throws IOException {  Properties prop = new Properties();  InputStream fis = new FileInputStream(this.configPath);  // 从输入流中读取属性列表(键和元素对)  prop.load(fis);  // 调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。  // 强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。  OutputStream fos = new FileOutputStream(this.configPath);  prop.setProperty(key, value);  // 以适合使用 load 方法加载到 Properties 表中的格式,  // 将此 Properties 表中的属性列表(键和元素对)写入输出流  prop.store(fos,"last update");  //关闭文件  fis.close();  fos.close(); }  /** * @return the props */ public Properties getProps() { return props; } public static void main(String[] args) {  PropertiesUtil p;  try {   p = new PropertiesUtil("conf/ip-black.properties");   Enumeration en = p.props.propertyNames();   String str="";   while (en.hasMoreElements()) {    String key = (String) en.nextElement();    System.out.println(key);   }  } catch (IOException e) {   // TODO Auto-generated catch block   e.printStackTrace();  } } }

附上黑名单IP文件格式

ip-black.properties 配置文件

45.119.99.35
103.253.2.165
157.65.166.51
202.57.55.242
119.82.252.122
140.227.53.126
140.227.211.20
140.227.208.20
116.253.84.183

附加

之所以使用配置文件读取黑名单IP是为了加快数据读取速度,因为每次访问服务器都会被校验,使用数据库会加大数据库的压力,这个方法中每10秒就会重新读取配置文件缓存其实更好,不使用缓存主要是为了,因为放在缓存中还要写对应的操作方法,如果有什么更好的方法欢迎大家讨论。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表