前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >几行代码,搞定 SpringBoot 接口恶意刷新和暴力请求!

几行代码,搞定 SpringBoot 接口恶意刷新和暴力请求!

作者头像
芋道源码
发布2022-06-02 19:40:09
2830
发布2022-06-02 19:40:09
举报
文章被收录于专栏:芋道源码1024芋道源码1024

点击上方“芋道源码”,选择“设为星标

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 10:33?更新文章,每天掉亿点点头发...

源码精品专栏

来源:blog.csdn.net/wang_shuyu/

article/details/102531940/


在实际项目使用中,必须要考虑服务的安全性,当服务部署到互联网以后,就要考虑服务被恶意请求和暴力攻击的情况,下面的教程,通过interceptredis针对url+ip在一定时间内访问的次数来将ip禁用,可以根据自己的需求进行相应的修改,来打打自己的目的;

首先工程为springboot框架搭建,不再详细叙述。

直接上核心代码。

首先创建一个自定义的拦截器类,也是最核心的代码:

代码语言:javascript
复制
/**
?*?@package:?com.technicalinterest.group.interceptor
?*?@className:?IpUrlLimitInterceptor
?*?@description:?ip+url重复请求现在拦截器
?*?@author:?Shuyu.Wang
?*?@since:?0.1
?**/
@Slf4j
public?class?IpUrlLimitInterceptor?implements?HandlerInterceptor?{
?
?
?private?RedisUtil?getRedisUtil()?{
??return??SpringContextUtil.getBean(RedisUtil.class);
?}
?
?private?static?final?String?LOCK_IP_URL_KEY="lock_ip_";
?
?private?static?final?String?IP_URL_REQ_TIME="ip_url_times_";
?
?private?static?final?long?LIMIT_TIMES=5;
?
?private?static?final?int?IP_LOCK_TIME=60;
?
?@Override
?public?boolean?preHandle(HttpServletRequest?httpServletRequest,?HttpServletResponse?httpServletResponse,?Object?o)?throws?Exception?{
??log.info("request请求地址uri={},ip={}",?httpServletRequest.getRequestURI(),?IpAdrressUtil.getIpAdrress(httpServletRequest));
??if?(ipIsLock(IpAdrressUtil.getIpAdrress(httpServletRequest))){
???log.info("ip访问被禁止={}",IpAdrressUtil.getIpAdrress(httpServletRequest));
???ApiResult?result?=?new?ApiResult(ResultEnum.LOCK_IP);
???returnJson(httpServletResponse,?JSON.toJSONString(result));
???return?false;
??}
??if(!addRequestTime(IpAdrressUtil.getIpAdrress(httpServletRequest),httpServletRequest.getRequestURI())){
???ApiResult?result?=?new?ApiResult(ResultEnum.LOCK_IP);
???returnJson(httpServletResponse,?JSON.toJSONString(result));
???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?{
?
?}
?
?/**
??*?@Description:?判断ip是否被禁用
??*?@author:?shuyu.wang
??*?@date:?2019-10-12?13:08
??*?@param?ip
??*?@return?java.lang.Boolean
??*/
?private?Boolean?ipIsLock(String?ip){
??RedisUtil?redisUtil=getRedisUtil();
??if(redisUtil.hasKey(LOCK_IP_URL_KEY+ip)){
???return?true;
??}
??return?false;
?}
?/**
??*?@Description:?记录请求次数
??*?@author:?shuyu.wang
??*?@date:?2019-10-12?17:18
??*?@param?ip
??*?@param?uri
??*?@return?java.lang.Boolean
??*/
?private?Boolean?addRequestTime(String?ip,String?uri){
??String?key=IP_URL_REQ_TIME+ip+uri;
??RedisUtil?redisUtil=getRedisUtil();
??if?(redisUtil.hasKey(key)){
???long?time=redisUtil.incr(key,(long)1);
???if?(time>=LIMIT_TIMES){
????redisUtil.getLock(LOCK_IP_URL_KEY+ip,ip,IP_LOCK_TIME);
????return?false;
???}
??}else?{
???redisUtil.getLock(key,(long)1,1);
??}
??return?true;
?}
?
?private?void?returnJson(HttpServletResponse?response,?String?json)?throws?Exception?{
??PrintWriter?writer?=?null;
??response.setCharacterEncoding("UTF-8");
??response.setContentType("text/json;?charset=utf-8");
??try?{
???writer?=?response.getWriter();
???writer.print(json);
??}?catch?(IOException?e)?{
???log.error("LoginInterceptor?response?error?--->?{}",?e.getMessage(),?e);
??}?finally?{
???if?(writer?!=?null)?{
????writer.close();
???}
??}
?}
?
?
}

代码中redis的使用的是分布式锁的形式,这样可以最大程度保证线程安全和功能的实现效果。代码中设置的是1S内同一个接口通过同一个ip访问5次,就将该ip禁用1个小时,根据自己项目需求可以自己适当修改,实现自己想要的功能;

redis分布式锁的关键代码:

代码语言:javascript
复制
/**
?*?@package:?com.shuyu.blog.util
?*?@className:?RedisUtil
?*?@description:
?*?@author:?Shuyu.Wang
?*?@since:?0.1
?**/
@Component
@Slf4j
public?class?RedisUtil?{
?
?private?static?final?Long?SUCCESS?=?1L;
?
?@Autowired
?private?RedisTemplate<String,?Object>?redisTemplate;
?//?=============================common============================
?
?
?
?/**
??*?获取锁
??*?@param?lockKey
??*?@param?value
??*?@param?expireTime:单位-秒
??*?@return
??*/
?public?boolean?getLock(String?lockKey,?Object?value,?int?expireTime)?{
??try?{
???log.info("添加分布式锁key={},expireTime={}",lockKey,expireTime);
???String?script?=?"if?redis.call('setNx',KEYS[1],ARGV[1])?then?if?redis.call('get',KEYS[1])==ARGV[1]?then?return?redis.call('expire',KEYS[1],ARGV[2])?else?return?0?end?end";
???RedisScript<String>?redisScript?=?new?DefaultRedisScript<>(script,?String.class);
???Object?result?=?redisTemplate.execute(redisScript,?Collections.singletonList(lockKey),?value,?expireTime);
???if?(SUCCESS.equals(result))?{
????return?true;
???}
??}?catch?(Exception?e)?{
???e.printStackTrace();
??}
??return?false;
?}
?
?/**
??*?释放锁
??*?@param?lockKey
??*?@param?value
??*?@return
??*/
?public?boolean?releaseLock(String?lockKey,?String?value)?{
??String?script?=?"if?redis.call('get',?KEYS[1])?==?ARGV[1]?then?return?redis.call('del',?KEYS[1])?else?return?0?end";
??RedisScript<String>?redisScript?=?new?DefaultRedisScript<>(script,?String.class);
??Object?result?=?redisTemplate.execute(redisScript,?Collections.singletonList(lockKey),?value);
??if?(SUCCESS.equals(result))?{
???return?true;
??}
??return?false;
?}
?
}

最后将上面自定义的拦截器通过registry.addInterceptor添加一下,就生效了;

代码语言:javascript
复制
@Configuration
@Slf4j
public?class?MyWebAppConfig?extends?WebMvcConfigurerAdapter?{
????@Bean
?IpUrlLimitInterceptor?getIpUrlLimitInterceptor(){
?????return?new?IpUrlLimitInterceptor();
?}
?
?@Override
????public?void?addInterceptors(InterceptorRegistry?registry)?{
??registry.addInterceptor(getIpUrlLimitInterceptor()).addPathPatterns("/**");
????????super.addInterceptors(registry);
????}
}

自己可以写一个for循环来测试方面的功能,这里就不详细介绍了。



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了?MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复?666?领取,更多内容陆续奉上。

代码语言:javascript
复制
文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)
本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-06-02,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 芋道源码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com