Rumah >Java >javaTutorial >Bagaimana Spring Boot menghalang penyegaran antara muka berniat jahat dan permintaan kekerasan
Mula-mula buat kelas pemintas tersuai, yang juga merupakan kod teras;
/** * @package: com.technicalinterest.group.interceptor * @className: IpUrlLimitInterceptor * @description: ip+url重复请求现在拦截器 * @author: Shuyu.Wang * @date: 2019-10-12 12:34 * @since: 0.1 **/ @Slf4j public class IpUrlLimitInterceptor implements HandlerInterceptor { private RedisUtil getRedisUtil() { return SpringContextUtil.getBean(RedisUtil.class); } private static final String LOCK_IP_URL_KEY="lock_ip_"; private static final String IP_URL_REQ_TIME="ip_url_times_"; private static final long LIMIT_TIMES=5; private static final int IP_LOCK_TIME=60; @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { log.info("request请求地址uri={},ip={}", httpServletRequest.getRequestURI(), IpAdrressUtil.getIpAdrress(httpServletRequest)); if (ipIsLock(IpAdrressUtil.getIpAdrress(httpServletRequest))){ log.info("ip访问被禁止={}",IpAdrressUtil.getIpAdrress(httpServletRequest)); ApiResult result = new ApiResult(ResultEnum.LOCK_IP); returnJson(httpServletResponse, JSON.toJSONString(result)); return false; } if(!addRequestTime(IpAdrressUtil.getIpAdrress(httpServletRequest),httpServletRequest.getRequestURI())){ ApiResult result = new ApiResult(ResultEnum.LOCK_IP); returnJson(httpServletResponse, JSON.toJSONString(result)); 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 { } /** * @Description: 判断ip是否被禁用 * @author: shuyu.wang * @date: 2019-10-12 13:08 * @param ip * @return java.lang.Boolean */ private Boolean ipIsLock(String ip){ RedisUtil redisUtil=getRedisUtil(); if(redisUtil.hasKey(LOCK_IP_URL_KEY+ip)){ return true; } return false; } /** * @Description: 记录请求次数 * @author: shuyu.wang * @date: 2019-10-12 17:18 * @param ip * @param uri * @return java.lang.Boolean */ private Boolean addRequestTime(String ip,String uri){ String key=IP_URL_REQ_TIME+ip+uri; RedisUtil redisUtil=getRedisUtil(); if (redisUtil.hasKey(key)){ long time=redisUtil.incr(key,(long)1); if (time>=LIMIT_TIMES){ redisUtil.getLock(LOCK_IP_URL_KEY+ip,ip,IP_LOCK_TIME); return false; } }else { redisUtil.getLock(key,(long)1,1); } return true; } private void returnJson(HttpServletResponse response, String json) throws Exception { PrintWriter writer = null; response.setCharacterEncoding("UTF-8"); response.setContentType("text/json; charset=utf-8"); try { writer = response.getWriter(); writer.print(json); } catch (IOException e) { log.error("LoginInterceptor response error ---> {}", e.getMessage(), e); } finally { if (writer != null) { writer.close(); } } } }
Redis dalam kod menggunakan borang kunci yang diedarkan, yang boleh memastikan keselamatan benang dan realisasi fungsi ke tahap yang paling besar Kesan. Apa yang ditetapkan dalam kod ialah jika antara muka yang sama diakses melalui IP yang sama 5 kali dalam 1S, IP akan dilumpuhkan selama 1 jam Anda boleh mengubah suainya dengan sewajarnya mengikut keperluan projek anda untuk mencapai fungsi yang anda inginkan
redis Kod kunci kunci yang diedarkan:
/** * @package: com.shuyu.blog.util * @className: RedisUtil * @description: * @author: Shuyu.Wang * @date: 2019-07-14 14:42 * @since: 0.1 **/ @Component @Slf4j public class RedisUtil { private static final Long SUCCESS = 1L; @Autowired private RedisTemplate<String, Object> redisTemplate; // =============================common============================ /** * 获取锁 * @param lockKey * @param value * @param expireTime:单位-秒 * @return */ public boolean getLock(String lockKey, Object value, int expireTime) { try { log.info("添加分布式锁key={},expireTime={}",lockKey,expireTime); String script = "if redis.call('setNx',KEYS[1],ARGV[1]) then if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end end"; RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class); Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value, expireTime); if (SUCCESS.equals(result)) { return true; } } catch (Exception e) { e.printStackTrace(); } return false; } /** * 释放锁 * @param lockKey * @param value * @return */ public boolean releaseLock(String lockKey, String value) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class); Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value); if (SUCCESS.equals(result)) { return true; } return false; } }
Akhir sekali, tambahkan pemintas tersuai di atas melalui registry.addInterceptor dan ia akan berkuat kuasa;
Atas ialah kandungan terperinci Bagaimana Spring Boot menghalang penyegaran antara muka berniat jahat dan permintaan kekerasan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!