当前位置: 代码网 > it编程>编程语言>Java > SpringBoot接口恶意刷新和暴力请求的解决方法

SpringBoot接口恶意刷新和暴力请求的解决方法

2024年11月13日 Java 我要评论
在实际项目使用中,必须要考虑服务的安全性,当服务部署到互联网以后,就要考虑服务被恶意请求和暴力攻击的情况,下面的教程,通过intercept和redis针对url+ip在一定时间内访问的次数来将ip禁

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

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

直接上核心代码。

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

/**
 * @package: com.technicalinterest.group.interceptor
 * @classname: ipurllimitinterceptor
 * @description: ip+url重复请求现在拦截器
 **/
@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是否被禁用
  * @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: 记录请求次数
  * @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分布式锁的关键代码:

/**
 * @package: com.shuyu.blog.util
 * @classname: redisutil
 **/
@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添加一下,就生效了;

@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);
    }
}

到此这篇关于springboot接口恶意刷新和暴力请求的解决方法的文章就介绍到这了,更多相关springboot接口恶意刷新和暴力请求内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com