-
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)的使用
VB.NET eBook
Add-in and Automation Development In VB.NET 2003 (F
Add-in and Automation Development In VB.NET 2003 (8
Add-in and Automation Development in VB.NET 2003 (6
Add-in and Automation Development In VB.NET 2003 (5
AddIn Automation Development In VB.NET 2003 (4)
AddIn And Automation Development In VB.NET 2003 (2)
Addin and Automation Development In VB.NET 2003 (3)
AddIn And Automation Development In VB.NET 2003 (1)
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
武装你的WEBAPI-OData入门
武装你的WEBAPI-OData便捷查询
武装你的WEBAPI-OData分页查询
武装你的WEBAPI-OData资源更新Delta
5. 武装你的WEBAPI-OData使用Endpoint 05-09
武装你的WEBAPI-OData之API版本管理
武装你的WEBAPI-OData常见问题
武装你的WEBAPI-OData聚合查询
OData WebAPI实践-OData与EDM
OData WebAPI实践-Non-EDM模式