网站被攻击,恶意ip疯狂访问怎么办?( 二 )

/** * @param limitedIpMap * @param ip * @return true : 被限制 | false : 正常 * @Description 是否是被限制的IP */ private boolean isLimitedIP(Map<String, Long> limitedIpMap, String ip) { if (limitedIpMap == null || ip == null) { // 没有被限制 return false; } Set<String> keys = limitedIpMap.keySet(); Iterator<String> keyIt = keys.iterator(); while (keyIt.hasNext()) { String key = keyIt.next(); if (key.equals(ip)) { // 被限制的IP return true; } } return false; }接着就要判断当前访问的ip是否在限制Ip名单内 , 如果在 , 就进行拦截 , 不让其进行访问 。
// 获取IP存储器 Map<String, Long[]> ipMap = (Map<String, Long[]>) context.getAttribute("ipMap"); // 判断存储器中是否存在当前IP , 如果没有则为初次访问 , 初始化该ip // 如果存在当前ip , 则验证当前ip的访问次数 // 如果大于限制阀值 , 判断达到阀值的时间 , 如果不大于[用户访问最小安全时间]则视为恶意访问 , 跳转到异常页面 if (ipMap.containsKey(ip)) { Long[] ipInfo = ipMap.get(ip); ipInfo[0] = ipInfo[0] + 1; System.out.println("当前第[" + (ipInfo[0]) + "]次访问"); if (ipInfo[0] > LIMIT_NUMBER) { Long ipAccessTime = ipInfo[1]; Long currentTimeMillis = System.currentTimeMillis(); if (currentTimeMillis - ipAccessTime <= MIN_SAFE_TIME) { limitedIpMap.put(ip, currentTimeMillis + LIMITED_TIME_MILLIS); request.setAttribute("remainingTime", LIMITED_TIME_MILLIS); System.err.println("ip访问过于频繁:" + ip); request.getRequestDispatcher("/views/error.jsp").forward(request, response); return; } else { //初始化用户访问次数和访问时间 initIpVisitsNumber(ipMap, ip); } } //当ip访问时间与上一次访问时间相隔一分钟时 , 对该ip的访问次数 , 和时间进行重置 updateCurrentTimeIp(ipMap, ip); } else { //初始化用户访问次数和访问时间 initIpVisitsNumber(ipMap, ip); System.out.println("您首次访问该网站"); } context.setAttribute("ipMap", ipMap); chain.doFilter(request, response); /** * 初始化用户访问次数和访问时间 * * @param ipMap * @param ip */ private void initIpVisitsNumber(Map<String, Long[]> ipMap, String ip) { Long[] ipInfo = new Long[3]; ipInfo[0] = 0L;// 访问次数 ipInfo[1] = System.currentTimeMillis();// 初次访问时间 ipInfo[2] = System.currentTimeMillis(); ipMap.put(ip, ipInfo); } /** * @param updateCurrentTimeIp * @Description 当ip访问时间与上一次访问时间相隔一分钟时 , 对该Ip的访问次数 , 和时间进行重置 */ private void updateCurrentTimeIp(Map<String, Long[]> ipMap, String ip) { Long[] ipInfo = ipMap.get(ip); Long ipAccessTime = ipInfo[2]; Long currentTimeMillis = System.currentTimeMillis(); if (ipAccessTime != 0 && (currentTimeMillis - ipAccessTime) >= MIN_SAFE_TIME) { System.out.println("进来了"); Long[] longs = ipMap.get(ip); longs[0] = 0l; longs[1] = System.currentTimeMillis(); longs[2] = System.currentTimeMillis(); } }最后就是要判断该存储器中有没有当前ip , 没有就要存到ip存储器中 , 有的话就要根据当前ip访问次数和到达阀值时间进行判断是否需要拦截 , 这里有个ipUtil代码我没放上来 , 我现在方桑来 , 方便大家直接拿去用 , 是一个简单获取访问ip的工具类 。
/** ip访问限制 , 限制ip每分钟访问次数*** */public class IpUtil { public static String getIpAddr(ServletRequest servletRequest) { HttpServletRequest request=(HttpServletRequest) servletRequest; String ipAddress = null; try { ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if (ipAddress.equals("127.0.0.1")) { // 根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (Exception e) { e.printStackTrace(); } ipAddress = inet.getHostAddress(); } } // 对于通过多个代理的情况 , 第一个IP为客户端真实IP,多个IP按照','分割 if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() // = 15 if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } } catch (Exception e) { ipAddress=""; } // ipAddress = this.getRequest().getRemoteAddr(); return ipAddress; }}


推荐阅读