代码走查的时候走查老师提出建议对高频ip做限制,防止不法ip攻击,去网上看了很多方法,最多的就是自定义注解,然后定义一个注解的实现类利用aop去验证该限制接口的请求ip是否符合,但是缺点就是我们不可能每一个接口都要去加注解。
还有一种方法就是利用过滤器去验证每一个请求的ip,原文地址,感谢东哥(我们不生产代码,我们只是代码的搬运工_
下面附上代码:

过滤器:统计用户访问次数,记录访问时间、封禁时间
监听器:工程运行时初始化IP存储器(此处用的Map)

自定义过滤器:

/*** 自定义过滤器,用来判断IP访问次数是否超限* 如果前台用户访问网站的频率过快,则判定该ip恶意刷新操作,* 限制该IP的访问,1小时后自己解除限制*/
@WebFilter(urlPatterns = "/*")
public class MyIpFilter implements Filter {private static final Logger logger = LoggerFactory.getLogger(MyIpFilter.class);/*** 默认限制时间(单位:ms)*/private static final long LIMITED_TIME_MILLIS = 60 * 60 * 1000;/*** 用户连续访问最高阀值,超过该值则认定为恶意操作的IP,进行限制*/private static final int LIMIT_NUMBER = 50;/*** 用户访问最小安全时间,在该时间内如果访问次数大于阀值,则记录为恶意IP,否则视为正常访问*/private static final int MIN_SAFE_TIME = 1000;private FilterConfig config;@Overridepublic void init(FilterConfig filterConfig) {this.config = filterConfig;    //设置属性filterConfig}/*** (non-Javadoc)** @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)*/@SuppressWarnings("unchecked")@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;ServletContext context = config.getServletContext();Map<String, Long> limitedIpMap = (Map<String, Long>) context.getAttribute("limitedIpMap");filterLimitedIpMap(limitedIpMap);String ip = request.getRemoteHost();// 判断是否是被限制的IP,如果是则跳到异常页面if (isLimitedIP(limitedIpMap, ip)) {long limitedTime = limitedIpMap.get(ip) - System.currentTimeMillis();request.setAttribute("remainingTime", ((limitedTime / 1000) + (limitedTime % 1000 > 0 ? 1 : 0)));logger.error("IP访问过于频繁=>:" + ip);request.getRequestDispatcher("/error/requestLimit").forward(request, response);return;}// 获取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;logger.info("当前IP第[" + (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 / 1000) + (LIMITED_TIME_MILLIS % 1000 > 0 ? 1 : 0)));logger.error("IP访问过于频繁:" + ip);request.getRequestDispatcher("/error/requestLimit").forward(request, response);return;} else {initIpVisitsNumber(ipMap, ip);}}} else {initIpVisitsNumber(ipMap, ip);logger.info("首次访问该网站");}context.setAttribute("ipMap", ipMap);chain.doFilter(request, response);}@Overridepublic void destroy() {// TODO Auto-generated method stub}/*** @param limitedIpMap* @Description 过滤受限的IP,剔除已经到期的限制IP*/private void filterLimitedIpMap(Map<String, Long> limitedIpMap) {if (limitedIpMap == null) {return;}Set<String> keys = limitedIpMap.keySet();Iterator<String> keyIt = keys.iterator();long currentTimeMillis = System.currentTimeMillis();while (keyIt.hasNext()) {long expireTimeMillis = limitedIpMap.get(keyIt.next());if (expireTimeMillis <= currentTimeMillis) {keyIt.remove();}}}/*** @param limitedIpMap* @param ip* @return true : 被限制 | false : 正常* @Description 是否是被限制的IP*/private boolean isLimitedIP(Map<String, Long> limitedIpMap, String ip) {if (limitedIpMap.containsKey(ip)) {return true;}return false;}/*** 初始化用户访问次数和访问时间** @param ipMap* @param ip*/private void initIpVisitsNumber(Map<String, Long[]> ipMap, String ip) {Long[] ipInfo = new Long[2];ipInfo[0] = 0L;// 访问次数ipInfo[1] = System.currentTimeMillis();// 初次访问时间ipMap.put(ip, ipInfo);}
}

监听器:

@WebListener
public class MyApplicationListener implements ServletContextListener {private Logger logger = LoggerFactory.getLogger(MyApplicationListener.class);@Overridepublic void contextInitialized(ServletContextEvent sce) {logger.info("liting: contextInitialized");logger.info("MyApplicationListener初始化成功");ServletContext context = sce.getServletContext();// IP存储器Map<String, Long[]> ipMap = new HashMap<String, Long[]>();context.setAttribute("ipMap", ipMap);// 限制IP存储器:存储被限制的IP信息Map<String, Long> limitedIpMap = new HashMap<String, Long>();context.setAttribute("limitedIpMap", limitedIpMap);logger.info("ipmap:" + ipMap.toString() + ";limitedIpMap:" + limitedIpMap.toString() + "初始化成功-----");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {// TODO Auto-generated method stub}
}

然后在SpringBoot启动类添加扫描过滤器

@ServletComponentScan(basePackages = "com.ziding.product.cooperation.requestLimit")

如果被限制后将会转发到新的接口

@RestController
public class RequestLimit {/*** 对高频ip限制,携带剩余限制时间** @param request* @return*/@RequestMapping("/error/requestLimit")public ResultEntity requestLimitTime(HttpServletRequest request) {Object limitTime = request.getAttribute("remainingTime");return ResultTemplate.errorData(5001, "IP已被限制,请稍后在试~", limitTime);}
}

SpringBoot自定义过滤器实现高频IP限制访问相关推荐

  1. springboot 自定义过滤器

    springboot 自定义过滤器 Filter 过滤器主要是用来过滤用户请求的,它允许我们对用户请求进行前置处理和后置处理,比如实现 URL 级别的权限控制.过滤非法请求等等.Filter 过滤器是 ...

  2. Springboot过滤器禁止ip频繁访问功能实现

    在开发 Web 项目的时候,经常需要过滤器来处理一些请求,包括字符集转换什么的,记录请求日志什么的等等.在之前的 Web 开发中,我们习惯把过滤器配置到 web.xml 中,但是在 SpringBoo ...

  3. springboot过滤字段_SpringBoot自定义过滤器的两种方式及过滤器执行顺序

    第一种 @WebFilter + @ServletComponentScan 注解 1.首先自定义过滤器 如下自定义过滤器 ReqResFilter必须实现  javax.servlet.Filter ...

  4. springboot编写自定义过滤器

    springboot编写自定义过滤器 首先引入依赖,其次编写过滤器 @Configuration public class FilterRegisterConfig {@Beanpublic Filt ...

  5. springboot项目中使用shiro 自定义过滤器和token的方式___shiro使用token登录流程

    springboot项目中使用shiro 自定义过滤器和token的方式 实现步骤主要是以下几步: 1. 在项目中导入maven依赖 <dependency><groupId> ...

  6. 09_Filter过滤器(访问所有资源前,首先执行自定义过滤器类的doFilter方法)_Listener监听器(监听域对象的改变)

    Filter 什么是Web过滤器? 如何使用Filter过滤器? 自定义Filter类的生命周期 过滤器可以拦截哪些资源路径? 拦截方式配置:资源被访问的方式 过滤器链的默认执行顺序是什么? 如何配置 ...

  7. SpringBoot后端统计网站的IP访问次数及地区

    项目是用SpringBoot+Vue实现,前后端分离的,前端是用nginx部署的,虽说可以通过Nginx的日志来统计网站的IP的访问次数,但想在前端用图形化的方式来展示是不太可行的,所以我想着是在Sp ...

  8. springboot应用本地ip能访问,局域网下ip不能访问,处理

    问题: 启动 springboot 应用后发现 本地ip能直接访问,但是局域网下其他电脑却不能访问,那么一看就知道是 防火墙问题了, 那么如何设置呢? 打开 windows 防火墙 -> 允许应 ...

  9. .net中自定义过滤器对Response内容进行处理

    原文:http://www.cnblogs.com/zgqys1980/archive/2008/09/02/1281895.html 代码DEMO:http://files.cnblogs.com/ ...

最新文章

  1. Hadoop学习笔记一
  2. 联手Slack,IBM欲开发多元化智能聊天机器人
  3. 被神话的大数据——从大数据(big data)到深度数据(deep data)思维转变
  4. W3C XSL Transformations (XSLT) Version 2.0 翻译计划
  5. java web 程序---购物车项目内容:
  6. 'cross-env' 不是内部或外部命令,也不是可运行的程序
  7. FastMaskRCNN算法TensorFlow配置,训练
  8. 安装的python没有菜单栏_由非root用户安装python包/工具
  9. .net core WebAPI 初探及连接MySQL
  10. 深入原理64式:40 概率论公式总结
  11. Abis接口的概念和引发的商业策略
  12. 大火的扩散模型终于杀到了NLP领域
  13. 如何提取视频中的音频?自用方法介绍
  14. 自动安装第三方库python,python第三方库自动安装脚本
  15. 关于视频变速播放软件
  16. Java基础(学习笔记)
  17. 2021暑期积分赛一
  18. WM_CREATE ,WM_NCCREATE,WM_DESTROY,WM_NCDESTROY详解
  19. matlab的xcorr函数,Matlab_xcorr_互相关函数的讨论
  20. 平头哥RVB2601测评:对接阿里云物联网平台

热门文章

  1. Ubuntu搭建博客typecho
  2. hdu 5775 Bubble Sort
  3. 一场顶级学术会议一票难求背后,是AI产业热浪下学界的矛盾与茫然
  4. PostgreSQL的基础操作
  5. 通过rpm安装方式安装mysql
  6. 处男作《程序员第二步—从程序员到项目经理》分娩记之一
  7. wordpress登录插件_最受欢迎的WordPress登陆页面插件
  8. 06android studio创建模拟器
  9. 基于51单片机智能加湿器(程序+仿真+全套资料)
  10. SwiftUI 2.0 CoreData通过CloudKit同步公开数据库(WWDC20 讲稿)