婚礼案例网站,上海设计网站大全,seowhy论坛,什么是网络设计工作在实际项目开发部署过程中#xff0c;我们需要保证服务的安全性和可用性#xff0c;当项目部署到服务器后#xff0c;就要考虑服务被恶意请求和暴力攻击的情况。如何防止我们对外的接口被暴力攻击#xff1f;下面的教程#xff0c;通过Springboot提供的拦截器和Redis 针对…在实际项目开发部署过程中我们需要保证服务的安全性和可用性当项目部署到服务器后就要考虑服务被恶意请求和暴力攻击的情况。如何防止我们对外的接口被暴力攻击下面的教程通过Springboot提供的拦截器和Redis 针对IP在一定时间内访问的次数来将IP禁用拒绝服务
1、新建RedisUtil
RedisUtil用于缓存数据
Component
public class RedisUtil {Resourceprivate StringRedisTemplate stringRedisTemplate;/*** 取值* param key* return*/public String get(final String key) {return stringRedisTemplate.opsForValue().get(key);}/*** 是否存在键* param key* return*/public boolean hasKey(final String key){return Boolean.TRUE.equals(stringRedisTemplate.hasKey(key));}/*** 根据前缀正则获取所有键* param prefix* return*/public SetString getKeysByPattern(final String prefix){SetString keys this.getKeys(prefix.concat(*));return keys;}private SetString getKeys(String pattern){SetString keys stringRedisTemplate.execute((RedisCallbackSetString) connection - {SetString keysTmp new HashSet();Cursorbyte[] cursor connection.scan(new ScanOptions.ScanOptionsBuilder().match(pattern).count(1000).build());while (cursor.hasNext()) {keysTmp.add(new String(cursor.next()));}return keysTmp;});return keys;}/*** 设值时间单位为秒* param key* param value* param timeout* return*/public boolean set(final String key, String value, long timeout, TimeUnit timeUnit) {boolean result false;try {stringRedisTemplate.opsForValue().set(key, value, timeout, timeUnit);result true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 删除一个键值* param key* return*/public boolean delete(final String key) {boolean result false;try {stringRedisTemplate.delete(key);result true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 批量删除键值* param keys* return*/public boolean delete(CollectionString keys) {boolean result false;try {stringRedisTemplate.delete(keys);result true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 自增* param key* param value* param timeout* param timeUnit*/public void increment(String key, String value, long timeout, TimeUnit timeUnit){if(hasKey(key)){stringRedisTemplate.opsForValue().increment(key, Long.parseLong(value));}else {set(key, value, timeout, timeUnit);}}/*** 根据正则表达式删除所有键值* param pattern* return*/public boolean deleteAllByPattern(final String pattern){SetString keysByPattern getKeysByPattern(pattern);return delete(keysByPattern);}
}2、新建IPUtil
IPUtil用于获取客户端请求的IP
Component
public class IPUtil {public String getIpAddr(HttpServletRequest request) {String ipAddress;try {ipAddress request.getHeader(x-forwarded-for);if (ipAddress null || ipAddress.length() 0|| unknown.equalsIgnoreCase(ipAddress)) {ipAddress request.getHeader(Proxy-Client-IP);}if (ipAddress null || ipAddress.length() 0|| unknown.equalsIgnoreCase(ipAddress)) {ipAddress request.getHeader(WL-Proxy-Client-IP);}if (ipAddress null || ipAddress.length() 0|| unknown.equalsIgnoreCase(ipAddress)) {ipAddress request.getRemoteAddr();if (ipAddress.equals(127.0.0.1)) {// 根据网卡取本机配置的IPInetAddress inet null;try {inet InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}ipAddress inet.getHostAddress();}}// 对于通过多个代理的情况第一个IP为客户端真实IP,多个IP按照,分割if (ipAddress ! null ipAddress.length() 15) { // ***.***.***.***.length()// 15if (ipAddress.indexOf(,) 0) {ipAddress ipAddress.substring(0, ipAddress.indexOf(,));}}} catch (Exception e) {ipAddress ;}return ipAddress;}
}3、定义拦截器
拦截器代码如下该拦截器将记录一天内的单个IP的请求数量当请求数量达到1000时不再处理请求直接响应报错
Component
public class ViolentRequestInterceptor implements HandlerInterceptor {//配置文件配置最大请求数量//Value(${violentRequest.maxCount})//private int maxCount;private final int maxCount 1000;Autowiredprivate RedisUtil redisUtil;Autowiredprivate IPUtil ipUtil;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String ipAddr ipUtil.getIpAddr(request);String key ConstUtil.SYS_PREVENT_VIOLENT_REQUESTS ipAddr;if(!redisUtil.hasKey(key)){redisUtil.increment(key, String.valueOf(1), 1, TimeUnit.DAYS);}else {long count Long.parseLong(redisUtil.get(key));if(countmaxCount){JSONObject json (JSONObject) JSONObject.toJSON(Result.failure(HAVIOR_INVOKE_ERROR));response.setContentType(application/json;charsetUTF-8);response.getWriter().println(json);return false;}redisUtil.increment(key, String.valueOf(1), 1, TimeUnit.DAYS);}return true;}
}4、配置拦截器
配置拦截器对所有请求生效并设置优先级为1
Configuration
public class InterceptorConfig implements WebMvcConfigurer {Autowiredprivate ViolentRequestInterceptor violentRequestInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(violentRequestInterceptor).addPathPatterns(/**).order(1);}