From 665aa5d44c11f98e63e1e44044b52cdc4e6702f2 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Thu, 3 Sep 2026 15:46:42 +0900 Subject: [PATCH] =?UTF-8?q?"X-API-KEY=20=EB=B0=A9=EC=8B=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20=EB=82=B4=EB=B6=80=20API=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EA=B2=80=EC=A6=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20-=20ApiKeyInterceptor=20=EC=82=AD=EC=A0=9C,=20Inter?= =?UTF-8?q?nalApiTokenInterceptor=20=EB=8F=84=EC=9E=85=20-=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20config=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20X-Internal-Token=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=20-=20PortalPropertySer?= =?UTF-8?q?vice=20=EC=97=B0=EA=B4=80=20=EC=BD=94=EB=93=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=A0=9C=EA=B1=B0"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/InternalApiTokenService.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/eactive/apim/portal/common/internal/InternalApiTokenService.java b/src/main/java/com/eactive/apim/portal/common/internal/InternalApiTokenService.java index cd7f516..402f670 100644 --- a/src/main/java/com/eactive/apim/portal/common/internal/InternalApiTokenService.java +++ b/src/main/java/com/eactive/apim/portal/common/internal/InternalApiTokenService.java @@ -95,16 +95,15 @@ public class InternalApiTokenService { */ public boolean matches(String presented) { String expected = ensureToken(); - if (expected == null) { - log.error("내부 API 토큰({}/{})을 확보하지 못해 요청을 거부합니다.", PROP_GROUP, PROP_TOKEN); - return false; - } - if (isBlank(presented)) { - return false; - } - return MessageDigest.isEqual( - presented.trim().getBytes(StandardCharsets.UTF_8), - expected.getBytes(StandardCharsets.UTF_8)); + return tokenMatches(presented, expected); + } + + /** + * admin 등 토큰을 생성하면 안 되는 애플리케이션용 검증. + * 프로퍼티가 없으면 생성하지 않고 거부한다. + */ + public boolean matchesReadOnly(String presented) { + return tokenMatches(presented, findToken()); } /** 기동 시 1회 호출 — 헤더명/토큰 프로퍼티를 미리 만들어 둔다. (포탈 전용) */ @@ -138,6 +137,19 @@ public class InternalApiTokenService { } } + private boolean tokenMatches(String presented, String expected) { + if (expected == null) { + log.error("내부 API 토큰({}/{})을 확보하지 못해 요청을 거부합니다.", PROP_GROUP, PROP_TOKEN); + return false; + } + if (isBlank(presented)) { + return false; + } + return MessageDigest.isEqual( + presented.trim().getBytes(StandardCharsets.UTF_8), + expected.getBytes(StandardCharsets.UTF_8)); + } + /** JVM 당 1회만 생성되는 난수 토큰 (DB 에 값이 없을 때의 기본값). */ private String localToken() { String token = generatedToken.get();