如何离开客户端等待Java JAX-RS服务来防止DOS

我有一个Web服务的问题,用户试图通过循环随机ID猜测应用程序ID。

不好的请求来自随机的IP,所以我不能只是禁止他们的IP(除非我动态,但我还没有调查)。

目前,当我检测到一个客户端做了10个坏的应用程序ID尝试,我把它们放在我的应用程序的阻止列表,并拒绝该IP的进一步请求的一天。

我想要最小化我的服务器需要做的工作量,因为坏客户端将继续发送1000s的请求,即使它们被拒绝。我知道有动态防火墙解决方案,但想要一些容易实现在我的应用程序现在。目前我睡了5秒来减少调用,但我想做的只是不向客户端发送响应,所以它必须超时。

任何人知道如何做到这一点在Java,在JAX-RS?

我的服务就像,

@Path("/api")
public class MyServer {

@GET
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
@Path("/my-request")
public String myRequest(String type,
    @Context HttpServletRequest requestContext,
    @Context HttpServletResponse response) {
...
}

看到:
How to stop hack/DOS attack on web API

最佳答案
您正在寻找由JAX-RS支持的asynchronous responsestutorial for Jersey包含一些关于如何实现对请求的异步响应的示例。

使用异步响应,在请求完成之前,用于应答请求的线程被释放以处理另一请求。通过使用@Suspended注释添加参数来激活此功能。您需要做的额外,将注册一个专门的scheduler,负责唤醒您的请求后,在给定的超时,像这个例子:

@Path("/api")
public class MyServer {

  private ScheduledExecutorService scheduler = ...;

  @GET
  @Consumes(MediaType.APPLICATION_XML)
  @Produces(MediaType.APPLICATION_XML)
  @Path("/my-request")
  public String myRequest(String type,
                          @Context HttpServletRequest requestContext,
                          @Context HttpServletResponse response,
                          @Suspended AsyncResponse asyncResponse) {
    scheduler.schedule(new Runnable() {
      @Override
      public void run() {
        asyncResponse.resume(...)
      }
    }, 5, TimeUnit.SECOND);
  }
}

这样,在5秒的等待时间内没有线程被阻塞,这为同时处理其他请求提供了机会。

JAX-RS不提供在没有答案的情况下完全丢弃请求的方式。您需要保持连接打开以产生超时,如果您终止连接,用户不知道终止。最好的做法是不要回答异步请求,但这仍然会消耗一些资源。如果你想避免这种情况,你必须解决JAX-RS之外的问题,例如通过代理另一个服务器的请求。

一种方法是set up mod_proxy,您可以回答代理与错误代码的繁琐的请求,并设置一个非常大的重试限制这样的请求。

转载注明原文:如何离开客户端等待Java JAX-RS服务来防止DOS - 代码日志