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

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

/**
* @ProjectName: cdkj-framework
* @Package: com.cdkjframework.core.spring.filter
* @ClassName: FilterHandlerInterceptor
* @Description: 拦截过滤
* @Author: xiaLin
* @Date: 2022/6/22 13:36
* @Version: 1.0
*/
public class FilterHandlerInterceptor implements HandlerInterceptor { /**
* 日志
*/
private LogUtils logUtils = LogUtils.getLogger(FilterHandlerInterceptor.class); /**
* redis锁
*/
private final RedisLettuceLock redisLettuceLock; /**
* IP头部变量(可能通过Nginx代理后)
*/
private static final String HEADER_IP = "X-Real-IP"; /**
* 锁IP请求URL地址KEY
*/
private static final String LOCK_IP_URL_KEY = "lock_ip_"; /**
* IP请求URL地址时间
*/
private static final String IP_URL_REQ_TIME = "ip_url_times_"; /**
* 极限时间
*/
private static final long LIMIT_TIMES = 5; /**
* IP锁定时间 秒
*/
private static final int IP_LOCK_TIME = 60; /**
* 构建函数
*/
public FilterHandlerInterceptor(RedisLettuceLock redisLettuceLock) {
this.redisLettuceLock = redisLettuceLock;
} /**
* 预处理
*
* @param request 请求
* @param response 响应
* @param o 参数
* @return 返回结果
* @throws Exception 异常信息
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
String ip = request.getHeader(HEADER_IP);
if (StringUtils.isNullAndSpaceOrEmpty(ip)) {
ip = request.getRemoteAddr();
}
logUtils.info("request 请求地址 Uri={},ip={}", request.getRequestURI(), ip);
if (ipIsLock(ip)) {
logUtils.info("ip访问被禁止={}", ip);
ResponseBuilder builder = ResponseBuilder.failBuilder("ip访问被禁止");
returnJson(response, builder);
return false;
}
if (!addRequest(ip, request.getRequestURI())) {
ResponseBuilder builder = ResponseBuilder.failBuilder("ip访问被禁止");
returnJson(response, builder);
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 { } /**
* IP 是否已锁
*
* @param ip IP 地址
* @return 返回是否成功
*/
private Boolean ipIsLock(String ip) {
if (redisLettuceLock.lock(LOCK_IP_URL_KEY + ip)) {
return true;
}
return false;
} /**
* 添加请求信息
*
* @param ip IP 地址
* @param uri 请求路径
* @return 返回是否成功
*/
private Boolean addRequest(String ip, String uri) {
String key = IP_URL_REQ_TIME + ip + uri;
if (RedisUtils.syncExists(key)) {
long time = RedisUtils.syncIncr(key, IntegerConsts.ONE);
if (time >= LIMIT_TIMES) {
redisLettuceLock.lock(LOCK_IP_URL_KEY + ip, IP_LOCK_TIME, ip);
return false;
}
} else {
redisLettuceLock.lock(key, (long) IntegerConsts.ONE, IntegerConsts.ONE);
}
return true;
} /**
* 返回结果
*
* @param response 响应
* @param builder 返回结果
* @throws Exception 异常信息
*/
private void returnJson(HttpServletResponse response, ResponseBuilder builder) throws Exception {
ResponseUtils.out(response, builder);
}
}

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

/**
* @ProjectName: cdkj-framework
* @Package: com.cdkjframework.core.spring.filter
* @ClassName: WebMvcFilterConfigurerAdapter
* @Description: java类作用描述
* @Author: xiaLin
* @Date: 2022/6/22 13:37
* @Version: 1.0
*/
@RequiredArgsConstructor
public class WebMvcFilterConfigurerAdapter implements WebMvcConfigurer { /**
* redis锁
*/
private final RedisLettuceLock redisLettuceLock; /**
* 过虑句柄拦截器
*
* @return 返回拦截器
*/
@Bean
private FilterHandlerInterceptor filterHandlerInterceptor() {
return new FilterHandlerInterceptor(redisLettuceLock);
} /**
* 添加 拦截器
*
* @param registry 拦截器注册
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(filterHandlerInterceptor()).addPathPatterns("/**");
}
}

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

文章中的工具类可参考:https://gitee.com/cdkjframework/common/tree/1.0.2/

Spring Boot 防止接口被恶意刷新、暴力请求的更多相关文章

  1. spring boot rest 接口集成 spring security(2) - JWT配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  2. spring boot rest 接口集成 spring security(1) - 最简配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  3. Spring Boot Web应用开发 CORS 跨域请求支持:

    Spring Boot Web应用开发 CORS 跨域请求支持: 一.Web开发经常会遇到跨域问题,解决方案有:jsonp,iframe,CORS等等CORS与JSONP相比 1. JSONP只能实现 ...

  4. 46. Spring Boot中使用AOP统一处理Web请求日志

    在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...

  5. Spring boot CommandLineRunner接口使用例子

    前言 Spring boot的CommandLineRunner接口主要用于实现在应用初始化后,去执行一段代码块逻辑,这段初始化代码在整个应用生命周期内只会执行一次. 如何使用CommandLineR ...

  6. spring boot: 设计接口站api的版本号,支持次版本号(spring boot 2.3.2)

    一,为什么接口站的api要使用版本号? 1,当服务端接口的功能发生改进后, 客户端如果不更新版本,    则服务端返回的功能可能不能使用,    所以在服务端功能升级后,     客户端也要相应的使用 ...

  7. spring boot:给接口增加签名验证(spring boot 2.3.1)

    一,为什么要给接口做签名验证? 1,app客户端在与服务端通信时,通常都是以接口的形式实现, 这种形式的安全方面有可能出现以下问题: 被非法访问(例如:发短信的接口通常会被利用来垃圾短信) 被重复访问 ...

  8. 寻找写代码感觉(三)之使用 Spring Boot 编写接口

    一.前言 项目配置完之后,接着就是写接口了,那咱们就开始吧. 二.项目配置补充知识点 上篇文章写的是关于项目属性配置的一些知识,这里针对上次遗忘内容进行补充如下: 2.1.获取配置文件的值 在appl ...

  9. spring boot:使接口返回统一的RESTful格式数据(spring boot 2.3.1)

    一,为什么要使用REST? 1,什么是REST? REST是软件架构的规范体系,它把资源的状态用URL进行资源定位, 以HTTP动作(GET/POST/DELETE/PUT)描述操作 2,REST的优 ...

  10. spring boot 统一接口异常返回值

    创建业务 Exception 一般在实际项目中,推荐创建自己的 Exception 类型,这样在后期会更容易处理,也比较方便统一,否则,可能每个人都抛出自己喜欢的异常类型,而造成代码混乱 Servic ...

随机推荐

  1. 错误“AxImp.exe”已退出,代码为 -1163019603

    最近调试项目时突然出现错误"AxImp.exe"已退出,代码为 -1163019603 发现引用中的组件出现了一个感叹号 经过核对是锐浪报表的组件出现了问题,尝试打开报表设计器也无 ...

  2. conky配置(附配置项作用解释)

    alignment top_right #是否嵌入桌面 background yes #是否绘制窗口边框 draw_borders no #窗口边框 border_width 10 #cpu_avg_ ...

  3. 【Spark】Day04-Spark Streaming:与离线批量比较、架构特点、入门案例、创建(队列、数据源)、转换(有状态、无状态)、输出方式、进阶(累加、转换为DF、缓存持久化)、实战(窗口统计)

    一.概述 1.离线和实时计算 离线:数据量大,数据不会变化,MapReduce 实时:数据量小,计算过程要短 2.批量和流式处理 批量:冷数据,数据量大,速度慢 流:在线.实时产生的数据(快速持续到达 ...

  4. Java多线程详解(通俗易懂)

    一.线程简介 1. 什么是进程? 电脑中会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互独立存在的.例如图中的微信.酷狗音乐.电脑管家等等. 2. 什么是线程? 进程想要执行任务就需 ...

  5. php的可变变量覆盖漏洞

    题目如下: <?php highlight_file('source.txt'); echo "<br><br>"; $flag = 'xxxxxxx ...

  6. $_GET方法踩坑

    背景 写代码时,遇到一个奇怪的问题:小程序卡券解码接口老是报解码失败,苦寻了一个小时,发现原来是url参数经过thinkphp的I方法被过滤掉,而且涉及到PHP原生的$_GET 原因 I方法底层是原生 ...

  7. mybatis 之定义拦截器 控制台SQL的打印

    类型 先说明Mybatis中可以被拦截的类型具体有以下四种: 1.Executor:拦截执行器的方法.2.ParameterHandler:拦截参数的处理.3.ResultHandler:拦截结果集的 ...

  8. 万万没想到,go的数据库操作,也能像php一样溜了

    Hi,各位go的小伙伴. 很多人都是从php转过来的吧,不知道你们有没有发现,go界的orm并没有像php的orm一样好用.这篇文章里,我们认真的讨论下这个问题,并且会在后面提出解决方案. php的方 ...

  9. Spark详解(07-1) - SparkStreaming案例实操

    Spark详解(07-1) - SparkStreaming案例实操 环境准备 pom文件 <dependencies>     <dependency>         &l ...

  10. 高并发解决方案orleans实践

    开具一张图,展开来聊天.有从单个服务.consul集群和orleans来展开高并发测试一个小小数据库并发实例. 首先介绍下场景,创建一个order,同时去product表里面减掉一个库存.很简单的业务 ...