SpringBoot防止大量请求攻击的实现

 更新时间:2021年11月23日 10:26:54   作者:qykhhr  
在有些特定的时候需要加上IP访问时间限制,防止一个IP多次访问请求,本文主要介绍了SpringBoot防止大量请求攻击的实现,感兴趣的可以了解一下

我们使用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次请求,可以发现请求被拦截了多少

在这里插入图片描述

对于注解,我们也可以不使用它,但是我们需要在拦截器中写入固定的参数。

到此这篇关于SpringBoot防止大量请求攻击的实现的文章就介绍到这了,更多相关SpringBoot防止大量请求攻击内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 深入浅出讲解代理模式

    Java 深入浅出讲解代理模式

    代理模式是Java常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象
    2022-03-03
  • Spring事务失效场景的详细整理

    Spring事务失效场景的详细整理

    Spring 事务的传播特性说的是,当多个事务同时存在的时候,Spring 如何处理这些事务的特性,下面这篇文章主要给大家介绍了关于Spring事务失效场景的相关资料,需要的朋友可以参考下
    2022-02-02
  • springboot配置文件属性变量引用方式${}和@@用法及区别说明

    springboot配置文件属性变量引用方式${}和@@用法及区别说明

    这篇文章主要介绍了springboot配置文件属性变量引用方式${}和@@用法及区别说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • SpringBoot如何通过@Profile注解配置多环境

    SpringBoot如何通过@Profile注解配置多环境

    在Spring中,可以使用配置文件的方式来指定不同环境下所需要的配置信息,本文给大家介绍SpringBoot如何通过@Profile注解配置多环境,感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • js中去除字符串中所有的html标签代码实例

    js中去除字符串中所有的html标签代码实例

    这篇文章主要介绍了js中去除字符串中所有的html标签代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • Java如何将ResultSet结果集遍历到List中

    Java如何将ResultSet结果集遍历到List中

    这篇文章主要介绍了Java如何将ResultSet结果集遍历到List中问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • Java实现EasyCaptcha图形验证码的具体使用

    Java实现EasyCaptcha图形验证码的具体使用

    Java图形验证码,支持gif、中文、算术等类型,可用于Java Web、JavaSE等项目,下面就跟随小编一起来了解一下
    2021-08-08
  • mybatis 查询返回Map<String,Object>类型

    mybatis 查询返回Map<String,Object>类型

    本文主要介绍了mybatis 查询返回Map<String,Object>类型,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • SpringBoot整合Mybatis-Plus分页失效的解决

    SpringBoot整合Mybatis-Plus分页失效的解决

    本文主要介绍了SpringBoot整合Mybatis-Plus分页失效的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Spring 使用Validation 验证框架的问题详解

    Spring 使用Validation 验证框架的问题详解

    Spring Boot在内部通过集成hibernate-validation已经实现了JSR-349验证规范接口,在Spring Boot项目中只要直接使用就行了。 一般用在Controller中用于验证前端传来的参数。这篇文章给大家介绍Spring Validation 验证框架的相关知识,感兴趣的朋友一起看看吧
    2021-07-07

最新评论