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
| import com.alibaba.fastjson.JSON; import com.access.limit.action.AccessLimit; import com.access.limit.redis.RedisService; import com.access.limit.result.CodeMsg; import com.access.limit.result.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream;
@Component public class PreventAttackInterceptor extends HandlerInterceptorAdapter {
@Autowired private RedisService redisService;
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(handler instanceof HandlerMethod){
HandlerMethod hm = (HandlerMethod) handler;
AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class); if(accessLimit == null){ return true; } int seconds = accessLimit.seconds(); int maxCount = accessLimit.maxCount(); boolean login = accessLimit.needLogin(); String key = request.getRequestURI(); if(login){ key+=""+"1"; }
AccessKey ak = AccessKey.withExpire(seconds); Integer count = redisService.get(ak,key,Integer.class); if(count == null){ redisService.set(ak,key,1); }else if(count < maxCount){ redisService.incr(ak,key); }else{ render(response,CodeMsg.ACCESS_LIMIT_REACHED); return false; } }
return true;
} private void render(HttpServletResponse response, CodeMsg cm)throws Exception { response.setContentType("application/json;charset=UTF-8"); OutputStream out = response.getOutputStream(); String str = JSON.toJSONString(Result.error(cm)); out.write(str.getBytes("UTF-8")); out.flush(); out.close(); } }
|