From 326c7e274acd15c99764c679c9b030d2a017255d Mon Sep 17 00:00:00 2001 From: Ananya Banerjee Date: Wed, 8 Sep 2021 15:34:39 +0530 Subject: [PATCH] Adding custom filter for Request Header validation before the request is pre-processed by the controller --- .../hyland/webhook/WebhookApplication.java | 11 ++++ .../webhook/controller/WebhookController.java | 19 ++----- .../webhook/filter/HeaderValidatorFilter.java | 42 +++++++++++++++ src/main/resources/log4j2.xml | 48 +++++++++++++++++ src/main/resources/logback.xml | 53 ------------------- 5 files changed, 104 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/hyland/webhook/filter/HeaderValidatorFilter.java create mode 100644 src/main/resources/log4j2.xml delete mode 100644 src/main/resources/logback.xml diff --git a/src/main/java/com/hyland/webhook/WebhookApplication.java b/src/main/java/com/hyland/webhook/WebhookApplication.java index a3cc9f5..4e7f91f 100644 --- a/src/main/java/com/hyland/webhook/WebhookApplication.java +++ b/src/main/java/com/hyland/webhook/WebhookApplication.java @@ -1,7 +1,10 @@ package com.hyland.webhook; +import com.hyland.webhook.filter.HeaderValidatorFilter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; @SpringBootApplication public class WebhookApplication { @@ -10,4 +13,12 @@ public static void main(String[] args) { SpringApplication.run(WebhookApplication.class, args); } + @Bean + public FilterRegistrationBean headerValidatorFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new HeaderValidatorFilter()); + registrationBean.addUrlPatterns("*"); + return registrationBean; + } + } diff --git a/src/main/java/com/hyland/webhook/controller/WebhookController.java b/src/main/java/com/hyland/webhook/controller/WebhookController.java index 6a65d57..51f043b 100644 --- a/src/main/java/com/hyland/webhook/controller/WebhookController.java +++ b/src/main/java/com/hyland/webhook/controller/WebhookController.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.hyland.webhook.DTO.gen.RecordingCompletedSchema; import com.hyland.webhook.constants.WebHookConstants; -import org.springframework.beans.factory.annotation.Value; import lombok.extern.log4j.Log4j2; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,27 +14,19 @@ @Log4j2 public class WebhookController { - @Value("${zoom.verification.token}") - private String verificationToken; - @RequestMapping("/get") + @RequestMapping("/fetch") public String getNotification() { log.info("#### Hello Webhooks ##### "); return "Hello Webhooks!!!"; } - - @PostMapping - public ResponseEntity onRecordingCompleted(@RequestBody String requestBody, @RequestHeader(value = WebHookConstants.HOST) String host, @RequestHeader(value = WebHookConstants.USER_AGENT) String userAgent, @RequestHeader(value = WebHookConstants.AUTHORIZATION) String authToken) { + @PostMapping("/get") + public ResponseEntity onRecordingEventConsumption(@RequestBody String requestBody, @RequestHeader(value = WebHookConstants.HOST) String host, @RequestHeader(value = WebHookConstants.USER_AGENT) String userAgent) { log.debug("#### Incoming Webhook Notification from Zoom API ##### {}", requestBody); log.debug("#### Request Header Information ##### Host :: User Agent :: {} {} ", host, userAgent); try { - // verify if the event notification originated from Zoom - if (null != authToken && !authToken.equals(verificationToken)) { - log.debug("Invalid Verification Token"); - return new ResponseEntity<>(requestBody, HttpStatus.FORBIDDEN); - } //Convert JSON object to Java POJO ObjectMapper mapper = new ObjectMapper(); RecordingCompletedSchema recordingObject = mapper.readValue(requestBody, RecordingCompletedSchema.class); @@ -44,10 +35,6 @@ public ResponseEntity onRecordingCompleted(@RequestBody String requestBo // Validate if the event notification is for Recording Completed event subscribed if (recordingObject.getEvent().equals(WebHookConstants.RECORDING_COMPLETED)) { log.debug("Recording Completed Event Payload {} ::", recordingObject); - String contributor = "admin"; - String library = "XXXX"; - String licenseKey = "XXXX"; - } } catch (Exception e) { diff --git a/src/main/java/com/hyland/webhook/filter/HeaderValidatorFilter.java b/src/main/java/com/hyland/webhook/filter/HeaderValidatorFilter.java new file mode 100644 index 0000000..7070651 --- /dev/null +++ b/src/main/java/com/hyland/webhook/filter/HeaderValidatorFilter.java @@ -0,0 +1,42 @@ +package com.hyland.webhook.filter; + +import com.hyland.webhook.constants.WebHookConstants; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Log4j2 +public class HeaderValidatorFilter extends OncePerRequestFilter { + + @Value("${zoom.verification.token}") + private String verificationToken; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + String path = request.getRequestURI(); + log.info("#### path {} ##### ", path); + if ("/api/webhook/fetch".equals(path)) { + filterChain.doFilter(request, response); + return; + } + String authToken = request.getHeader(WebHookConstants.AUTHORIZATION); + log.info("#### validateToken {} ##### ", authToken); + + if (null != authToken && !authToken.equals(verificationToken)) { + response.sendError(HttpStatus.FORBIDDEN.value(), "Invalid Verification Token"); + log.debug("Invalid Verification Token"); + return; + } + + filterChain.doFilter(request, response); + } +} diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..0bed37d --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,48 @@ + + + + %d{yyyy-MM-dd'T'HH:mm:ss.SSSZ} %p %C{1.} [%t] %m%n + + + + + + + + + + + + + + 50MB + 30 + 3GB + + + UTF-8 + %date [%thread] [%X{X-B3-TraceId:-}.%X{X-B3-ParentSpanId:-}] %-5p %class{0}:%L %M - %m%n + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml deleted file mode 100644 index 477d07f..0000000 --- a/src/main/resources/logback.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - ${log.base}/${log.name} - - ${log.base}/${name}.%d{yyyy-MM-dd}.%i.log - 50MB - 30 - 3GB - - - UTF-8 - %date [%thread] [%X{X-B3-TraceId:-}.%X{X-B3-ParentSpanId:-}] %-5p %class{0}:%L %M - %m%n - - - - - ${log.base}/${name}-error.log - - ${log.base}/${name}-error.%d{yyyy-MM-dd}.%i.log - 50MB - 30 - 3GB - - - UTF-8 - %date [%thread] [%X{X-B3-TraceId:-}.%X{X-B3-ParentSpanId:-}] %-5p %class{0}:%L %M - %m%n - - - ERROR - ACCEPT - DENY - - - - - - UTF-8 - %date [%thread] [%X{X-B3-TraceId:-}.%X{X-B3-ParentSpanId:-}] %-5p %class{0}:%L %M - %m%n - - - - - - - - - \ No newline at end of file