代码走查的时候走查老师提出建议对高频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. 使用Vant框架的组件van-pull-refresh搭配van-list和van-card完成上滑加载更多列表数据,下拉刷新当前列表数据(等同于翻页功能)
  2. java注释@para_Java中文档注释各字段的含义是什么?例如author表示作者,para表示参数等...
  3. C++ 设计People类-1
  4. python 判断是否是int/string/类型的函数
  5. 浅谈AI视频技术超分辨率
  6. 消费者广播模式和负载均衡模式
  7. linux chrome 安装过程记录
  8. 第四章 生命周期函数--35 vue-resource发起get、post、jsonp请求
  9. python tts 保存_Python 文件和目录操作学习
  10. java写入文件的几种方法分享
  11. m序列生成方法及其fpga实现
  12. 希捷移动硬盘打不开怎么办?
  13. DA14580外设篇之GPIO中断
  14. python录入数据,python处理写入数据教学教程
  15. 入坑张银奎老师研发的GDK7
  16. 计算机组成原理:中央处理器(2)
  17. Windows文件夹中文名称英文路径
  18. 填词作文:新的一年,新的梦想
  19. 你怎么不招聘 DBA
  20. 【C语言】0x1F<<11等于0还是0xF800 ?

热门文章

  1. 域名需要备案吗?什么条件下域名不用备案?
  2. 金属电子逸出功的测定实验报告_土壤重金属测定仪介绍#
  3. 【数据分析师自学系列——python】python实现自动挂号代码
  4. xsspayload
  5. 2022年R2移动式压力容器充装复审模拟考试及R2移动式压力容器充装考试试题
  6. 清晰还原31年前现场,火山引擎超清修复Beyond经典演唱会
  7. RPC框架性能优化思路和具体实现
  8. npm 、yarn、pnpm、nvm 、nrm、 npx介绍
  9. anaconda prompt、labelimg安装使用
  10. 0-6岁是专注力发展的最佳时期,根据不同年龄培养娃的专注力!