Implemented an interceptor, that forbiddes access according to a header
[demos/spring-boot] / src / main / java / de / juplo / demo / RequestTypeInterceptor.java
diff --git a/src/main/java/de/juplo/demo/RequestTypeInterceptor.java b/src/main/java/de/juplo/demo/RequestTypeInterceptor.java
new file mode 100644 (file)
index 0000000..fa1f428
--- /dev/null
@@ -0,0 +1,88 @@
+package de.juplo.demo;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import java.io.IOException;
+
+
+@Component
+@Slf4j
+public class RequestTypeInterceptor implements HandlerInterceptor
+{
+  public final static String REQUEST_TYPE = "X-Request-Type";
+
+  public enum RequestType { HUMAN, MACHINE };
+
+
+  @Override
+  public boolean preHandle(
+      HttpServletRequest request,
+      HttpServletResponse response,
+      Object handler) throws IOException
+  {
+    //  Only instances of HandlerMethod are intercepted for the type of the request
+    if (!(handler instanceof HandlerMethod))
+    {
+      log.trace("Ignoring handler of type {}", handler);
+      return true;
+    }
+
+    String requestTypeHeader = request.getHeader(REQUEST_TYPE);
+    if (requestTypeHeader == null)
+    {
+      sendBadRequest(response, "Ignoring request without header");
+      return false;
+    }
+
+    try
+    {
+      RequestType requestType = RequestType.valueOf(requestTypeHeader.toUpperCase());
+
+      if (requestType == RequestType.MACHINE)
+      {
+        log.debug("Accepting machine-request for {}", handler);
+        return true;
+      }
+
+      if (((HandlerMethod)handler).getMethod().getAnnotation(RequestableByHumans.class) != null)
+      {
+        log.info("Accepting human request for {}", handler);
+        return true;
+      }
+      else
+      {
+        sendForbidden(response, "Human requests are not allowed for " + handler);
+        return false;
+      }
+    }
+    catch (IllegalArgumentException e)
+    {
+      log.warn("Invalid RequestType: {}", e.toString());
+    }
+
+    sendBadRequest(response, requestTypeHeader);
+    return false;
+  }
+
+  void sendForbidden(
+      HttpServletResponse response,
+      String message) throws IOException
+  {
+    log.warn("Forbidden: {}", message);
+    response.sendError(HttpStatus.FORBIDDEN.value(), message);
+  }
+
+  void sendBadRequest(
+      HttpServletResponse response,
+      String message) throws IOException
+  {
+    log.warn("Bad request: {}", message);
+    response.sendError(HttpStatus.BAD_REQUEST.value(), message);
+  }
+}