java - 如何让客户端等待 Java JAX-RS 服务以防止 DOS

标签 java web-services rest jax-rs ddos

我在使用 Web 服务时遇到问题,用户试图通过循环随机 ID 来猜测应用程序 ID。

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

目前,当我检测到一个客户端尝试了 10 次错误的应用 ID 尝试时,我会将它们放在我的应用中的阻止列表中,并在当天拒绝来自该 IP 的进一步请求。

我想尽量减少我的服务器需要做的工作量,因为坏客户端即使被拒绝也会继续发送 1000 多个请求。我知道有动态防火墙解决方案,但现在想要在我的应用程序中轻松实现。目前我正在 sleep 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

最佳答案

您正在寻找 asynchronous responses JAX-RS 支持。 tutorial 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 - 如何让客户端等待 Java JAX-RS 服务以防止 DOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32874305/

相关文章:

web-services - z/OS 如何调用 Web 服务?

php - 在服务器端使用 PHP 并在客户端使用 GWT 构建网站的好例子?

java - 用于传递错误消息的索引参数的 REST API

java - UNCODE/espace 特殊字符 JSON 数据 Spring MVC

Java 泽西客户端 API

java - 在 REST Assured 中,如何检查响应中是否存在某个字段?

java - 无法选择损坏的布局上的任何元素

java - 接口(interface)方法的使用(Java)?

java - 泛型方法 : static vs NON-static

java - Java或C++中的递归广度优先旅行函数?