SpringBoot의 사용자 정의 메모 구현 컨트롤러 액세스 횟수 제한 사례
웹에서 가장 자주 발생하는 것은 악성 URL을 이용하여 폭발 서버에 접근하는 것과 같은 공격입니다. 오늘은 사용자 정의 주석을 이용하여 이러한 공격을 어떻게 방어하는지 소개해 드리겠습니다.
사실 이런 문제의 일반적인 해결 사고방식은 컨트롤러에 사용자 정의 주석을 넣어 방문 횟수를 제한하는 기능을 실현하는 것이다.
구체적인 실현 과정은 다음과 같다.
1단계: 먼저 주석 클래스를 정의하고 코드 사례를 보십시오.
package example.controller.limit;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
//
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RequestLimit {
/**
*
* , MAX_VALUE
*/
int count() default Integer.MAX_VALUE;
/**
*
* , ,
*/
long time() default 60000;
}
단계 2: URL 공격을 처리할 때 발생하는 이상 문제를 처리하기 위해 이상 클래스를 정의합니다. 다음은 코드 사례를 보십시오.
package example.controller.exception;
public class RequestLimitException extends Exception {
private static final long serialVersionUID = 1364225358754654702L;
public RequestLimitException() {
super("HTTP ");
}
public RequestLimitException(String message) {
super(message);
}
}
단계 3: 주해의 구체적인 실현 유형을 정의하고 다음은 코드 사례를 본다.
package example.controller.limit;
import example.controller.exception.RequestLimitException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
@Aspect
@Component
public class RequestLimitContract {
private static final Logger logger = LoggerFactory.getLogger("RequestLimitLogger");
private Map<String, Integer> redisTemplate=new HashMap<String,Integer>();
@Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)")
public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException {
try {
Object[] args = joinPoint.getArgs();
HttpServletRequest request = null;
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof HttpServletRequest) {
request = (HttpServletRequest) args[i];
break;
}
}
if (request == null) {
throw new RequestLimitException(" HttpServletRequest ");
}
String ip = request.getLocalAddr();
String url = request.getRequestURL().toString();
String key = "req_limit_".concat(url).concat(ip);
if(redisTemplate.get(key)==null || redisTemplate.get(key)==0){
redisTemplate.put(key,1);
}else{
redisTemplate.put(key,redisTemplate.get(key)+1);
}
int count = redisTemplate.get(key);
if (count > 0) {
Timer timer= new Timer();
TimerTask task = new TimerTask(){ // 。
@Override
public void run() {
redisTemplate.remove(key);
}
};
timer.schedule(task, limit.time());
// 。task : 。10000 : , 。
}
if (count > limit.count()) {
//logger.info(" IP[" + ip + "] [" + url + "] [" + limit.count() + "]");
throw new RequestLimitException();
}
} catch (RequestLimitException e) {
throw e;
} catch (Exception e) {
logger.error(" : ", e);
}
}
}
4단계: 제어 클래스를 실현하고 주석 기능을 추가합니다.코드 사례를 살펴보겠습니다.
package example.controller;
import example.controller.limit.RequestLimit;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@Controller
public class URLController {
@RequestLimit(count=10,time=5000)
@RequestMapping("/urltest")
@ResponseBody
public String test(HttpServletRequest request, ModelMap modelMap) {
return "aaa";
}
}
그 중에서count는 규정된 시간 내의 방문 횟수를 가리키고time는 규정된 시간을 가리키며 단위는 밀리초이다.이렇게 하면 컨트롤러라는 차원에서 URL을 차단할 수 있다.그러나 여기에 문제가 하나 있다. 모든 URL 페이지에서 이런 차단을 하려면 이런 방법이 현저히 부족하다는 것이다.모든 컨트롤러에 URL 차단 주석을 추가할 수 없기 때문에 이런 방법은 특정한 URL 차단 위에서만 사용하기에 적합하다.
그러면 필터 레벨 위의 URL 접근 차단을 어떻게 실현합니까?여기서 먼저 여러분께 스위치를 하나 드리겠습니다. 다음 절에서 필터를 이용하여 URL 접근 차단을 어떻게 하는지, 그리고 JPA를 이용하여 IP 블랙리스트의 기능을 실현하는지, IP 블랙리스트를 가입하면 어떠한 URL도 접근할 수 없습니다.
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.