From 97489d0361dd9205e28d90707cfd9d562034c7f2 Mon Sep 17 00:00:00 2001 From: Rinjae-gf63 Date: Thu, 3 Sep 2026 09:19:46 +0900 Subject: [PATCH] =?UTF-8?q?-=20PasswordDecryptFilter=EC=97=90=20/internal/?= =?UTF-8?q?**=20=EA=B2=BD=EB=A1=9C=20=EC=A0=9C=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80=20-=20=EB=82=B4=EB=B6=80=20API?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD=20=ED=95=84=ED=84=B0=20=EB=8F=99=EC=9E=91?= =?UTF-8?q?/=EC=95=94=ED=98=B8=ED=99=94=20=EC=A0=95=EC=B1=85=20=EC=B6=A9?= =?UTF-8?q?=EB=8F=8C=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../passwordcrypto/PasswordDecryptFilter.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/apim/portal/common/security/passwordcrypto/PasswordDecryptFilter.java b/src/main/java/com/eactive/apim/portal/common/security/passwordcrypto/PasswordDecryptFilter.java index 767f525..d12b251 100644 --- a/src/main/java/com/eactive/apim/portal/common/security/passwordcrypto/PasswordDecryptFilter.java +++ b/src/main/java/com/eactive/apim/portal/common/security/passwordcrypto/PasswordDecryptFilter.java @@ -24,10 +24,19 @@ import java.io.IOException; * *

기능이 꺼져 있거나 POST 가 아니면 아무것도 하지 않는다. 래퍼는 파라미터를 조회할 때만 * 복호화하므로, 봉투가 없는 요청에는 사실상 비용이 없다.

+ * + *

{@code /internal/**} 은 대상에서 제외한다. playwright 전용 테스트 정리 API + * ({@code TestCleanupInternalController} 등)는 공유 토큰({@code X-Internal-Token}) + IP 허용목록으로 + * 이미 인증되는 서버-to-서버 호출이라 브라우저 암호화 대상이 아니다({@code MenuAccessInterceptor} 가 + * 같은 이유로 {@code /internal/**} 을 제외하는 것과 동일 패턴). 이 경로를 필터에 그대로 태우면, 도구가 + * 보내는 평문 {@code password} 파라미터가 {@code plaintext-policy=ENFORCE} 설정에 걸려 빈 문자열로 + * 치환되고 내부 API 는 "필수값 누락"으로 거부한다(예: {@code /internal/test-cleanup/password}).

*/ @Component public class PasswordDecryptFilter implements Filter { + private static final String INTERNAL_API_PREFIX = "/internal/"; + private final PasswordCryptoProperties properties; private final PasswordEnvelopeCodec codec; private final PasswordKeyStore keyStore; @@ -50,7 +59,7 @@ public class PasswordDecryptFilter implements Filter { } HttpServletRequest httpRequest = (HttpServletRequest) request; - if (!"POST".equalsIgnoreCase(httpRequest.getMethod())) { + if (!"POST".equalsIgnoreCase(httpRequest.getMethod()) || isInternalApiRequest(httpRequest)) { chain.doFilter(request, response); return; } @@ -64,4 +73,9 @@ public class PasswordDecryptFilter implements Filter { wrapper.consumeUsedKeys(); } } + + private static boolean isInternalApiRequest(HttpServletRequest request) { + String path = request.getRequestURI().substring(request.getContextPath().length()); + return path.startsWith(INTERNAL_API_PREFIX); + } }