SpringBoot防止大量请求攻击

SpringBoot防止大量请求攻击我们使用Jmeter测试同学的网站时,就会出现网站无法访问,403等错误。Anerroroccurred.Sorry,thepageyouarelookingforiscurrentlyunavailable.Pleasetryagainlater.Ifyouarethesystemadministratorofthisresourcethenyoushouldchecktheerrorlogfordetails.Faithfull

大家好,又见面了,我是你们的朋友全栈君。

我们使用Jmeter测试同学的网站时,就会出现网站无法访问,403等错误。

An error occurred. Sorry, the page you are looking for is currently unavailable. Please try again later. If you are the system administrator of this resource then you should check the error log for details. Faithfully yours, nginx.

所以我们需要加上IP访问时间限制,防止一个IP多次访问请求,导致整个网站崩溃。

  • 自定义注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** * 自定义注解,用于拦截过于频繁的请求 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit { 
   
    int seconds();
    int maxCount();
    boolean needLogin() default true;
}
  • 自定义拦截器:
    我采用了抛出自定义异常的方式来解决相同IP多次访问的问题:
    throw new DujiaoshouException(20001,"操作过于频繁");
import com.qykhhr.dujiaoshouservice.exceptionhandler.DujiaoshouException;
import com.qykhhr.dujiaoshouservice.mycomment.AccessLimit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/** * 自定义拦截器 */
@Component
public class AccessLimtInterceptor implements HandlerInterceptor { 
   

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
   

        if (handler instanceof HandlerMethod) { 
   
            HandlerMethod hm = (HandlerMethod) handler;
            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
            if (null == accessLimit) { 
   
                return true;
            }
            int seconds = accessLimit.seconds();
            int maxCount = accessLimit.maxCount();
            boolean needLogin = accessLimit.needLogin();

            if (needLogin) { 
   
                //判断是否登录
            }
            String ip=request.getRemoteAddr();
            String key = request.getServletPath() + ":" + ip ;
            Integer count = (Integer) redisTemplate.opsForValue().get(key);

            if (null == count || -1 == count) { 
   
                redisTemplate.opsForValue().set(key, 1,seconds, TimeUnit.SECONDS);
                return true;
            }

            if (count < maxCount) { 
   
                count = count+1;
                redisTemplate.opsForValue().set(key, count,0);
                return true;
            }

            // response 返回 json 请求过于频繁请稍后再试
            throw new DujiaoshouException(20001,"操作过于频繁");
        }

        return true;
    }
}
  • 在webconfig中配置拦截器

import com.qykhhr.dujiaoshouservice.Interceptor.AccessLimtInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/** * 在webconfig中配置拦截器 */
@Configuration
public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter { 
   

    @Autowired
    private AccessLimtInterceptor accessLimtInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) { 
   
        registry.addInterceptor(accessLimtInterceptor);
        super.addInterceptors(registry);
    }
}

  • 在Controller前面加上注解就可以生效了
@RestController
public class AppHomeController { 
   

    @GetMapping("/index")
    @AccessLimit(seconds = 1, maxCount = 3) //1秒内 允许请求3次
    public R getImageList(){ 
   
        return R.ok().data("appHome","hahaha");
    }
}

使用python发送100次请求,可以发现请求被拦截了多少
在这里插入图片描述
对于注解,我们也可以不使用它,但是我们需要在拦截器中写入固定的参数。

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/162102.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 最小生成树的个数_最小生成树的实际应用

    最小生成树的个数_最小生成树的实际应用给定一张 N 个点 M 条边的无向图,求无向图的严格次小生成树。设最小生成树的边权之和为 sum,严格次小生成树就是指边权之和大于 sum 的生成树中最小的一个。输入格式第一行包含两个整数 N 和 M。接下来 M 行,每行包含三个整数 x,y,z,表示点 x 和点 y 之前存在一条边,边的权值为 z。输出格式包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)数据范围N≤105,M≤3×105输入样例:5 61 2 11 3 22 4 33 5 4

    2022年8月10日
    3
  • centos 安装 使用本地图像文件来安装网络安装「建议收藏」

    centos 安装 使用本地图像文件来安装网络安装

    2022年1月17日
    40
  • WiFi测试规范总结

    WiFi测试规范总结当移植好一款wifi模块后,需要到检测机构去检测各项指标,取得相关认证。这时有必要了解下WiFi测试的相关测试内容,以便更好地跟测试机构人员交流。

    2022年7月20日
    20
  • linux ubuntu 关闭防火墙命令,Linux下开启/关闭防火墙命令「建议收藏」

    iptables用于过滤数据包,属于网络层防火墙.firewall能够允许哪些服务可用,那些端口可用….属于更高一层的防火墙。firewall的底层是使用iptables进行数据过滤,建立在iptables之上。1)永久性生效,重启后不会复原开启:chkconfigiptableson关闭:chkconfigiptablesoff2)即时生效,重启后复原开启:service…

    2022年4月9日
    208
  • 数组截取数据slice()函数「建议收藏」

    数组截取数据slice()函数「建议收藏」JavaScriptslice()方法定义和用法slice()方法可从已有的数组中返回选定的元素。语法arrayObject.slice(start,end)参数描述start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1指最后一个元素,-2指倒数第二个元素,以此类推。end 可选。 必需。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从start到数组结束的所

    2022年6月2日
    30
  • RewriteRule指令[通俗易懂]

    RewriteRule指令[通俗易懂]作为RewriteRule指令的第三个参数。Flags是一个包含以逗号分隔的下列标记的列表: ‘last|L'(最后一个规则last)立即停止重写操作,并不再应用其他重写规则。它对应于Perl中的last命令或C语言中的break命令。这个标记可以阻止当前已被重写的URL为其后继的规则所重写。举例,使用它可以重写根路径的URL(‘/’)为实际存在的URL,比如,’/e/w

    2022年5月14日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号