-
Spring Boot 防止接口被恶意刷新、暴力请求
在实际项目使用中,必须要考虑服务的安全性,当服务部署到互联网以后,就要考虑服务被恶意请求和暴力攻击的情况,下面的教程,通过Spring Boot提供的HandlerInterceptor和Redis 针对 Url + ip在一定时间内访问的次数来将ip禁用,可以根据自己的业务需求进行相应的修改,以达到自己的目的。
首先创建一个自定义的拦截器类,也是最核心的代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/** * @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添加一下,就生效了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
/** * @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/
出处:https://www.cnblogs.com/cdkj/p/17134389.html
栏目列表
最新更新
Objective-C语法之代码块(block)的使用
URL Encode
python爬虫学习
python爬虫学习——列表
go语言写http踩得坑
【Python】爬虫笔记-从PyMySQL到DBUtils
【Python】爬虫笔记-开源代理池haipproxy使用
Python规范:提高可读性
C语言两结构体之间的成员互换
【爬虫实战项目】Python爬取Top100电影榜单
SQLSERVER 的复合索引和包含索引到底有啥区
华为云云原生数据库:A Philosophy about “
T-SQL 模拟彩票预测
SQLSERVER 事务日志的 LSN 到底是什么?
SQLSERVER 的 nolock 到底是怎样的无锁?
SQLSERVER 的四个事务隔离级别到底怎么理解
SQL Server清除小数点有效数字后的所有0
SQLSERVER 快照隔离级别 到底怎么理解?
SQLSERVER 阻塞之 PFS 页到底是什么?
优化数仓业务视图:过滤条件传递
解决未知的服务器标记“asp:ListView”。
css样式显示省略号
浅谈JS词法环境
js对象的理解
原型和原型链的深入浅出
JavaScript实现数组对象去重
关于 NodeJs 处理超长字符串问题的分析
JavaScript中的函数
使用JS的DOM(文档对象模型)获取前端循
JS web sql database 几个功能组合的实现