From 8ed365d316ef5215ca467c6f216be3910ee4cfbb Mon Sep 17 00:00:00 2001 From: elive7 Date: Tue, 17 Dec 2024 19:23:47 +0900 Subject: [PATCH] =?UTF-8?q?[hotfix]=20fix:=20slack=20interaction=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../slack/controller/SlackController.java | 5 +-- .../recordy/server/slack/domain/Slack.java | 2 +- .../slack/interceptor/SlackInterceptor.java | 34 ++++++------------- 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/recordy/server/slack/controller/SlackController.java b/src/main/java/org/recordy/server/slack/controller/SlackController.java index c54d96e3..39456bb7 100644 --- a/src/main/java/org/recordy/server/slack/controller/SlackController.java +++ b/src/main/java/org/recordy/server/slack/controller/SlackController.java @@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.util.ContentCachingRequestWrapper; @RestController @RequestMapping("/api/v1/slack/interactive") @@ -25,9 +24,7 @@ public class SlackController { public ResponseEntity handleInteractiveMessage(HttpServletRequest request) { try { System.out.println("request = " + request); - HttpServletRequest cachingRequest = new ContentCachingRequestWrapper(request); - System.out.println("cachingRequest = " + cachingRequest); - Slack slack = new Slack(cachingRequest); + Slack slack = new Slack(request); String actionId = slack.getActionId(); if (actionId.contains("report")) { diff --git a/src/main/java/org/recordy/server/slack/domain/Slack.java b/src/main/java/org/recordy/server/slack/domain/Slack.java index 79a1f93b..a61b714d 100644 --- a/src/main/java/org/recordy/server/slack/domain/Slack.java +++ b/src/main/java/org/recordy/server/slack/domain/Slack.java @@ -23,7 +23,7 @@ public class Slack { public Slack(HttpServletRequest request) { JSONObject json = getJsonFrom(request); - System.out.println(json); + System.out.println("json = " + json); JSONObject action = json.getJSONArray("actions").getJSONObject(0); JSONObject value = new JSONObject(action.getString("value")); diff --git a/src/main/java/org/recordy/server/slack/interceptor/SlackInterceptor.java b/src/main/java/org/recordy/server/slack/interceptor/SlackInterceptor.java index a37a82fd..1ad119ab 100644 --- a/src/main/java/org/recordy/server/slack/interceptor/SlackInterceptor.java +++ b/src/main/java/org/recordy/server/slack/interceptor/SlackInterceptor.java @@ -1,11 +1,8 @@ package org.recordy.server.slack.interceptor; -import static java.nio.charset.StandardCharsets.UTF_8; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.io.BufferedReader; -import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; @@ -26,7 +23,9 @@ public class SlackInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request); + ContentCachingRequestWrapper requestWrapper = (request instanceof ContentCachingRequestWrapper) + ? (ContentCachingRequestWrapper) request + : new ContentCachingRequestWrapper(request); String method = request.getMethod(); String signature = request.getHeader("X-Slack-Signature"); @@ -43,41 +42,30 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons } private String getRequestBody(ContentCachingRequestWrapper requestWrapper) { - StringBuilder stringBuilder = new StringBuilder(); - String line; - - try (BufferedReader reader = requestWrapper.getReader()) { - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - } - } catch (IOException e) { + byte[] buf = requestWrapper.getContentAsByteArray(); + if (buf.length == 0) { throw new SlackException(ErrorMessage.FAILED_TO_READ_SLACK_REQUEST); } - - return stringBuilder.toString(); + return new String(buf, StandardCharsets.UTF_8); } private boolean isValidRequest(String payload, String signature, String timestamp) { try { - // Slack 검증용 문자열 생성 String baseString = "v0:" + timestamp + ":" + payload; Mac mac = Mac.getInstance("HmacSHA256"); - SecretKeySpec secret = new SecretKeySpec(SLACK_SIGNING_SECRET.getBytes(UTF_8), "HmacSHA256"); + SecretKeySpec secret = new SecretKeySpec(SLACK_SIGNING_SECRET.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); mac.init(secret); - byte[] rawHmac = mac.doFinal(baseString.getBytes(UTF_8)); + byte[] rawHmac = mac.doFinal(baseString.getBytes(StandardCharsets.UTF_8)); - // HMAC 결과값을 16진수 문자열로 변환 StringBuilder sb = new StringBuilder(); for (byte b : rawHmac) { sb.append(String.format("%02x", b)); } - String calculatedSignature = "v0=" + sb; // 'v0='을 포함한 서명 생성 + String calculatedSignature = "v0=" + sb; - // 서명 전체를 비교 (constant-time 비교 사용) - return MessageDigest.isEqual(calculatedSignature.getBytes(UTF_8), signature.getBytes(UTF_8)); + return MessageDigest.isEqual(calculatedSignature.getBytes(StandardCharsets.UTF_8), signature.getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { throw new SlackException(ErrorMessage.FALIED_TO_MATCH_SLACK_SIGNATURE_EXCEPTION); } } } -