From dd255bb474caea1b5138d9dc5d7de586299c1277 Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 12 Dec 2025 08:39:59 +0900 Subject: [PATCH 1/4] =?UTF-8?q?transactionProp=EC=97=90=20isParameterType?= =?UTF-8?q?=3Dtrue=EC=9D=BC=EB=95=8C=20INBOUND=5FQUERY=5FSTRING=EC=B2=98?= =?UTF-8?q?=EC=9E=A5=20=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/eactive/eai/adapter/service/ApiAdapterService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java b/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java index a9f1bbe..6ce7b1b 100644 --- a/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java +++ b/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java @@ -151,6 +151,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport { if (isParameterType) { paramValue = request.getQueryString(); + transactionProp.put(INBOUND_QUERY_STRING, StringUtils.defaultString(paramValue)); // Filter에서 QueryString 검증을 위해 저장 if (paramValue == null) paramValue = ""; if (traceLevel >= 3) { From 61de36cbd4894ee31929441ccc6f5c2e2308fdad Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 12 Dec 2025 09:09:28 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=ED=86=A0=ED=81=B0=EB=B0=9C=EA=B8=89URL=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95(/mapi?= =?UTF-8?q?/oauth2/token)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eactive/eai/adapter/controller/ApiAdapterController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java b/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java index f79e0a1..6d8d7db 100644 --- a/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java +++ b/src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java @@ -50,10 +50,10 @@ public class ApiAdapterController implements HttpAdapterServiceKey { ApiAdapterService service; /** - * KBANK 요구사항으로 /api/v1/oauth/token 과 같은 형태로 토큰 발급거래를 수행해야해서 예외처리함 + * KJBANK 요구사항으로 /mapi/oauth2/token 과 같은 형태로 토큰 발급거래를 수행해야해서 예외처리함 * @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer endpoints) */ - @RequestMapping(value = {"/api/*", "/mapi/*", "/api/*/{path:^(?!.*oauth).*$}/**", "/mapi/*/{path:^(?!.*oauth).*$}/**"}) + @RequestMapping(value = {"/api/*", "/mapi/*", "/api/*/{path:^(?!.*oauth).*$}/**", "/mapi/{path:^(?!.*oauth2).*$}/**"}) // @RequestMapping(value = {"/api/**"}) public ResponseEntity callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception { // /ONLWeb/api/v1/public/getUserInfo.svc From f52ce1fe3f39f9083b9bbc370733cd5f7ab2825c Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 12 Dec 2025 10:01:08 +0900 Subject: [PATCH 3/4] =?UTF-8?q?KJB=20HMAC-SHA256=20Filter=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/KjbHmacSha256VerifyFilter.java | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java diff --git a/src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java b/src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java new file mode 100644 index 0000000..8cee22b --- /dev/null +++ b/src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java @@ -0,0 +1,144 @@ +package com.eactive.eai.custom.adapter.http.dynamic.filter; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Properties; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.net.util.Base64; +import org.springframework.http.HttpStatus; +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter; +import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.common.util.Logger; + +public class KjbHmacSha256VerifyFilter implements HttpAdapterFilter, HttpAdapterServiceKey { + + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private static final String SERVICE_CODE_UNKNOWN = "00"; + + @Override + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + String inboundMethod = prop.getProperty(INBOUND_METHOD); + String inboundUri = prop.getProperty(INBOUND_URI); + String inboundBody = prop.getProperty(INBOUND_REQUEST_MESSAGE); + + try { + String xObpPartnercode = request.getHeader("x-obp-partnercode"); + String xObpSignatureUrl = request.getHeader("x-obp-signature-url"); + String xObpSignatureBody = request.getHeader("x-obp-signature-body"); + if (StringUtils.isBlank(xObpPartnercode) || StringUtils.isBlank(xObpSignatureUrl) || StringUtils.isBlank(xObpSignatureBody)) { + throw new JwtAuthException(String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), "Can not find mandatory Http Header"); + } + + if (StringUtils.isNotBlank(prop.getProperty(INBOUND_QUERY_STRING))) { + inboundUri = inboundUri + "?" + prop.getProperty(INBOUND_QUERY_STRING); + inboundBody = ""; + } + String chkUrl = inboundMethod + "&" + inboundUri; + String chkBody = inboundBody; + String clientSecret = assignClientSecret(prop, request); + + String macUrl = calculateHMAC(chkUrl, clientSecret); + String macBody = calculateHMAC(chkBody, clientSecret); + + if (!StringUtils.equals(xObpSignatureUrl, macUrl)) { + throw new JwtAuthException( + String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + "Signature verifying failed : x-obp-signature-url"); + } + + if (!StringUtils.equals(xObpSignatureBody, macBody)) { + throw new JwtAuthException( + String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + "Signature verifying failed : x-obp-signature-body"); + } + + } catch (JwtAuthException e) { + logger.debug(e.getMessage()); + throw e; + } catch (Exception e) { + logger.error(e.getMessage()); + throw new JwtAuthException( + String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + "Signature verifying failed(unkown)"); + } + + return message; + } + + public static String calculateHMAC(String data, String key) + throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException { + + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(key.getBytes(), "HmacSHA256")); + return Base64.encodeBase64String(mac.doFinal(data.getBytes("UTF-8"))); + } + + private String assignClientSecret(Properties prop, HttpServletRequest request) throws Exception { + String clientId = assignClientId(prop, request); + if (StringUtils.isBlank(clientId)) { + throw new JwtAuthException( + String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + "Can not find clientId info"); + } + + ClientVO client = (ClientVO) OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId); + if (client == null) { + throw new JwtAuthException( + String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + "Can not find client info"); + } + + return client.getClientSecret(); + } + + private String assignClientId(Properties prop, HttpServletRequest request) { + String clientId = null; + try { + // 이전 filter에서 셋팅한 clientId 확보 + clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + + // 이전 filter에서 셋팅한 값이 없다면 header 정보에서 확보 + if (StringUtils.isBlank(clientId)) { + clientId = request.getHeader(HttpAdapterServiceSupport.HEADER_NAME_CLIENT_ID); + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return clientId; + } + + @Override + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + String outboundBody = (String) resultMessage; + + try { + String clientSecret = assignClientSecret(prop, request); + String macBody = calculateHMAC(outboundBody, clientSecret); + + response.addHeader("x-obp-signature-body", macBody); + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return resultMessage; + } + +} From 0578a3e84de29e62853c90a1a1863a9dce3af96f Mon Sep 17 00:00:00 2001 From: "Yunsam.Eo" Date: Fri, 12 Dec 2025 10:02:03 +0900 Subject: [PATCH 4/4] =?UTF-8?q?KJB=20HMAC-SHA256=20Filter=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/KjbHmacSha256VerifyFilter.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java b/src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java index 8cee22b..2ef0367 100644 --- a/src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java +++ b/src/main/java/com/eactive/eai/custom/adapter/http/dynamic/filter/KjbHmacSha256VerifyFilter.java @@ -40,8 +40,12 @@ public class KjbHmacSha256VerifyFilter implements HttpAdapterFilter, HttpAdapter String xObpPartnercode = request.getHeader("x-obp-partnercode"); String xObpSignatureUrl = request.getHeader("x-obp-signature-url"); String xObpSignatureBody = request.getHeader("x-obp-signature-body"); - if (StringUtils.isBlank(xObpPartnercode) || StringUtils.isBlank(xObpSignatureUrl) || StringUtils.isBlank(xObpSignatureBody)) { - throw new JwtAuthException(String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), "Can not find mandatory Http Header"); + if (StringUtils.isBlank(xObpPartnercode) + || StringUtils.isBlank(xObpSignatureUrl) + || StringUtils.isBlank(xObpSignatureBody)) { + throw new JwtAuthException( + String.valueOf(HttpStatus.UNAUTHORIZED.value()), + "Can not find mandatory Http Header"); } if (StringUtils.isNotBlank(prop.getProperty(INBOUND_QUERY_STRING))) { @@ -57,13 +61,13 @@ public class KjbHmacSha256VerifyFilter implements HttpAdapterFilter, HttpAdapter if (!StringUtils.equals(xObpSignatureUrl, macUrl)) { throw new JwtAuthException( - String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + String.valueOf(HttpStatus.UNAUTHORIZED.value()), "Signature verifying failed : x-obp-signature-url"); } if (!StringUtils.equals(xObpSignatureBody, macBody)) { throw new JwtAuthException( - String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + String.valueOf(HttpStatus.UNAUTHORIZED.value()), "Signature verifying failed : x-obp-signature-body"); } @@ -73,7 +77,7 @@ public class KjbHmacSha256VerifyFilter implements HttpAdapterFilter, HttpAdapter } catch (Exception e) { logger.error(e.getMessage()); throw new JwtAuthException( - String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + String.valueOf(HttpStatus.UNAUTHORIZED.value()), "Signature verifying failed(unkown)"); } @@ -92,14 +96,14 @@ public class KjbHmacSha256VerifyFilter implements HttpAdapterFilter, HttpAdapter String clientId = assignClientId(prop, request); if (StringUtils.isBlank(clientId)) { throw new JwtAuthException( - String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + String.valueOf(HttpStatus.UNAUTHORIZED.value()), "Can not find clientId info"); } ClientVO client = (ClientVO) OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId); if (client == null) { throw new JwtAuthException( - String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_UNKNOWN, "00"), + String.valueOf(HttpStatus.UNAUTHORIZED.value()), "Can not find client info"); }