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 77b80b4..8540290 100644 --- a/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java +++ b/src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java @@ -1,526 +1,799 @@ -package com.eactive.eai.adapter.service; - -import com.eactive.eai.adapter.AdapterGroupVO; -import com.eactive.eai.adapter.AdapterPropManager; -import com.eactive.eai.adapter.AdapterVO; -import com.eactive.eai.adapter.Keys; -import com.eactive.eai.adapter.http.HttpMemoryLogger; -import com.eactive.eai.adapter.http.HttpMethodType; -import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; -import com.eactive.eai.common.exception.ExceptionUtil; -import com.eactive.eai.common.message.MessageType; -import com.eactive.eai.common.util.CommonLib; -import com.eactive.eai.common.util.Logger; -import com.eactive.eai.inbound.action.ActionFactory; -import com.eactive.eai.inbound.action.RequestAction; -import com.eactive.eai.inbound.processor.Processor; -import com.eactive.eai.message.StandardMessageUtil; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.StopWatch; -import org.apache.mina.common.ByteBuffer; -import org.json.simple.JSONObject; -import org.json.simple.JSONValue; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Service; -import org.springframework.util.AntPathMatcher; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.net.URLDecoder; -import java.util.*; - -//for encrypt/decrypt jwhong -import com.eactive.eai.authserver.service.OAuth2Manager; -import com.kjbank.encrypt.exchange.crypto.AES256Cipher; -import com.kjbank.encrypt.exchange.crypto.AESCipher; -import java.nio.charset.StandardCharsets; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import org.springframework.security.oauth2.provider.ClientDetails; - -@Service -public class ApiAdapterService extends HttpAdapterServiceSupport { - static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); - - public static final String HEADER_GROUP = "HEADER_GROUP"; - // HEADER_GROUP JSON에 추가할 항목 정의, 없으면 전체 header 추가 - public static final String HEADER_KEYS = "HEADER_KEYS"; - public static final String PROPERTIES_NAME_HTTP_REQUEST_METHOD = "httpRequestMethod"; - - private static final String JSON_CONTENT_TYPE = "application/json"; - private static final String JSON_FIELD_NAME = "json-body"; - private static final String FILE_GROUP_NAME = "image-file"; - private static final String UPLOAD_ROOT_PATH = "UPLOAD_ROOT_PATH"; - - public String callApi(HttpServletRequest request, HttpServletResponse response, Properties httpProp, AdapterGroupVO adapterGroupVO, AdapterVO adapterVO, Properties transactionProp) throws Exception { - int traceLevel = 0; - - AdapterPropManager manager = null; - String adptGrpName = adapterGroupVO.getName(); - String adptName = adapterVO.getName(); - - - String urlDecodeYn = httpProp.getProperty(URL_DECODE_YN, "N"); - String encode = StringUtils.defaultIfBlank(adapterGroupVO.getMessageEncode(), "UTF-8"); - - String traceLevelTemp = httpProp.getProperty(TRACE_LEVEL, "0"); - String relayRequestHeaderKeys = httpProp.getProperty(HEADER_KEYS); - String headerGroupName = httpProp.getProperty(HEADER_GROUP); - - boolean isParameterType = false; - String message = null; - - String paramValue = null; - String adptMsgType = null; - - transactionProp.put(INBOUND_METHOD, request.getMethod()); - transactionProp.put(INBOUND_URI, request.getRequestURI()); - transactionProp.put(INBOUND_HEADER, getHeaders(request)); - if (StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) - || StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { - // /api/v1/public/getUserInfo.svc - String extUrl = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); - transactionProp.put(INBOUND_EXTURI, extUrl); - } else { - transactionProp.put(INBOUND_EXTURI, getExtUri(request)); - } - transactionProp.put(INBOUND_CLIENT_IP, getClientIp(request)); // Client IP 추가 - transactionProp.put(Processor.REQUEST_ACTION, adapterVO.getAdapterGroupVO().getRefClass()); - transactionProp.put(API_PATH, httpProp.getProperty(API_PATH, "")); - transactionProp.put(PRE_FILTERS, httpProp.getProperty(PRE_FILTERS, "")); - transactionProp.put(POST_FILTERS, httpProp.getProperty(POST_FILTERS, "")); - transactionProp.put(PROPERTIES_NAME_HTTP_REQUEST_METHOD, request.getMethod()); - transactionProp.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); - - transactionProp.put(ENC_PATHS, httpProp.getProperty(ENC_PATHS, "")); - - transactionProp.put(ENCRYPT_ALGORITHM, httpProp.getProperty(ENCRYPT_ALGORITHM, "")); //jwhong - transactionProp.put(HEADER_NAME_CLIENT_ID, getHeaders(request).get(HEADER_NAME_CLIENT_ID)); // jwhong - transactionProp.put(ENCRYPT_BASE_TYPE, httpProp.getProperty(ENCRYPT_BASE_TYPE, "")); //jwhong - //transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN)); // jwhong - transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN) != null ? getHeaders(request).get(INBOUND_TOKEN) : ""); //jwhong , null 이면 default로 "" put - - - try { - traceLevel = Integer.parseInt(traceLevelTemp); - } catch (Exception e) { - traceLevel = 0; - } - - StopWatch stopWatch = new StopWatch(); - stopWatch.start(); - - logger.debug("시작 >> encode = [" + encode + "]"); - - switch (HttpMethodType.getValue(request.getMethod())) { - case GET: - case DELETE: - isParameterType = true; - break; - case POST: - case PUT: - if (StringUtils.contains(request.getContentType(), "application/x-www-form-urlencoded")) { - isParameterType = true; - } else { - isParameterType = false; - } - break; - default: - break; - } - - if (isParameterType) { - paramValue = request.getQueryString(); - if (paramValue == null) - paramValue = ""; - if (traceLevel >= 3) { - HttpMemoryLogger.txlog(adptGrpName + adptName, - "RECV " + "[" + paramValue + "]" + CommonLib.getDumpMessage(paramValue)); - } - - // json으로 변환 - StringBuilder sb = new StringBuilder(); - sb.append("{"); - Map paramMap = assignParameterMap(request, adptGrpName, adptName, null, transactionProp); - int i = 0; - for (Map.Entry entry : paramMap.entrySet()) { - if (i > 0) { - sb.append(","); - } - sb.append("\"").append(entry.getKey()).append("\":"); - String[] values = entry.getValue(); - if (values.length > 1) { - // ["111", "222"] - sb.append("["); - for (int j = 0; j < values.length; j++) { - if (j > 0) { - sb.append(","); - } - sb.append("\"").append(JSONValue.escape(values[j])).append("\""); - } - sb.append("]"); - } else { - sb.append("\"").append(JSONValue.escape(values[0])).append("\""); - } - - i++; - } - - sb.append("}"); - - paramValue = sb.toString(); - - if (logger.isDebug()) { - logger.debug("HttpAdapterServiceRest] RECV (" + adptGrpName + ") = [" + paramValue + "]\n" - + CommonLib.getDumpMessage(paramValue.getBytes(encode))); - } - } else { - ServletInputStream sis = request.getInputStream(); - ByteBuffer bb = ByteBuffer.allocate(1024).setAutoExpand(true); - int i = 0; - byte[] cbuf = new byte[1024]; - while ((i = sis.read(cbuf, 0, 1024)) != -1) { - if (i == 1024) { - bb.put(cbuf); - } else { - byte[] tail = new byte[i]; - System.arraycopy(cbuf, 0, tail, 0, i); - bb.put(tail); - } - } - byte[] data = new byte[bb.position()]; - bb.position(0); - bb.get(data); - paramValue = new String(data, encode); - - if (traceLevel >= 3) { - HttpMemoryLogger.txlog(adptGrpName + adptName, - "RECV " + "[" + paramValue + "]" + CommonLib.getDumpMessage(data)); - } - - if (logger.isDebug()) { - logger.debug("HttpAdapterServiceRest] RECV (" + adptGrpName + ") = [" + paramValue + "]\n" - + CommonLib.getDumpMessage(data)); - } - } - - if (paramValue == null) { // parameter가 없는 경우때문에 처리 - paramValue = ""; - } - else { // jwhong decrypt - paramValue = doPreDecryption(paramValue, transactionProp); - } - - if ("Y".equals(urlDecodeYn) && isParameterType) { - message = URLDecoder.decode(paramValue); - } else { - message = paramValue; - } - - if (logger.isDebug()) { - String[] msgArgs = new String[2]; - msgArgs[0] = adptGrpName; - msgArgs[1] = message; - String resMsg = ExceptionUtil.make("RICEAIAHA005", msgArgs); - logger.debug(resMsg); - } - - - adptMsgType = adapterVO.getAdapterGroupVO().getMessageType(); -// HttpHeaders responseHeaders = new HttpHeaders(); -// responseHeaders.setContentType(MediaType.valueOf("application/json;charset=" + encode)); - - - // HEADER_GROUP 셋팅 - if (MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName) - && StringUtils.isNotBlank(relayRequestHeaderKeys)) { - JSONObject jsonMessage = (JSONObject) JSONValue.parse(message); - JSONObject headerJson = new JSONObject(); - if (StringUtils.equalsIgnoreCase(relayRequestHeaderKeys, "ALL")) { - for (Enumeration e = request.getHeaderNames(); e.hasMoreElements(); ) { - String key = e.nextElement(); - headerJson.put(key, request.getHeader(key)); - } - } else { - String[] relayKeyArr = org.springframework.util.StringUtils - .tokenizeToStringArray(relayRequestHeaderKeys, ","); - - for (String key : relayKeyArr) { - String headerValue = request.getHeader(key); - if (StringUtils.isNotBlank(headerValue)) { - headerJson.put(key, headerValue); - } - } - } - - if (headerJson.size() > 0) { - jsonMessage.put(headerGroupName, headerJson); - message = jsonMessage.toJSONString(); - } - } - - if (message == null) { - message = ""; - } - - transactionProp.put(INBOUND_REQUEST_MESSAGE, message); - // 로컬 서비스 호출 ,encoding 처리 추가 - String result = (String) service(adptGrpName, adptName, message, transactionProp, request, response); - - if (logger.isDebug()) { - logger.debug("HttpAdapterServiceRest] result " + encode + " (" + adptGrpName + ") = [" + result + "]"); - } - - stopWatch.stop(); - - String syncAsyncType = transactionProp.getProperty(INBOUND_SYNC_ASYNC_TYPE); - if (!"ASYN".equals(syncAsyncType) && MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName)) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode rootNode = (ObjectNode) mapper.readTree(result); - JsonNode headerGroup = rootNode.get(headerGroupName); - if(headerGroup != null) { - for(Iterator it = headerGroup.fieldNames(); it.hasNext();) { - String name = it.next(); - String value = headerGroup.get(name).asText(); - response.addHeader(name, value); - } - rootNode.remove(headerGroupName); - result = mapper.writeValueAsString(rootNode); - } - } - - return result; - } - - - // jwhong encrypt - - private String doPreDecryption(String eaiBody, Properties transactionProp) { - String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, ""); - String xElinkClientId = transactionProp.getProperty(HEADER_NAME_CLIENT_ID, ""); // 이 값이 OAuth의 client id 값이다 . http header 에 포함되어 온다. jwhong - String encryptBaseKeyType = transactionProp.getProperty(ENCRYPT_BASE_TYPE); - String inboundToken = transactionProp.getProperty(INBOUND_TOKEN, ""); - - if ( decryptAlgorithm == "" ) { // 복호화 대상이 아님 - return eaiBody; - } - - // 암호화 key를 token 내용으로 할지 client secret 내용으로 할지 결정함. adapter property에 정의함 - // ENCRYPT_ALGORITHM 을 설정했는데 ENCRYPT_BASE_TYPE을 설정안하면 Decrypt 수행시 Exception 발생함 - String clientSecret = ""; - if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { - clientSecret = inboundToken; - } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { - OAuth2Manager manager = OAuth2Manager.getInstance(); - ClientDetails clientDetail = manager.getClientDeatilsStore().get(xElinkClientId); - - if ( clientDetail != null ) { - clientSecret = clientDetail.getClientSecret(); - } - } - - byte[] decryptedMessage = null; - decryptedMessage = doInboundPreDecrypt(eaiBody, decryptAlgorithm,clientSecret); - - String resultMessage = new String(decryptedMessage, StandardCharsets.UTF_8 ); - return resultMessage; - //return new String(decryptedMessage, StandardCharsets.UTF_8 ); - } - - - private byte[] convertObjectToBytes(Object obj) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(obj); - oos.flush(); - return bos.toByteArray(); - } - - private byte[] convertObjectToBase64Bytes(Object obj) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(obj); - oos.flush(); - oos.close(); - - // 직렬화된 byte[] → Base64 문자열 → 다시 byte[]로 변환 - String base64String = Base64.getEncoder().encodeToString(bos.toByteArray()); - return base64String.getBytes(StandardCharsets.UTF_8); - } - - public static Object convertBytesToObject(byte[] bytes) throws IOException, ClassNotFoundException { - try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); - ObjectInputStream ois = new ObjectInputStream(bis)) { - return ois.readObject(); - } - } - - - private byte[] doInboundPreDecrypt(String eaiStringBody, String decryptAlgorithm, String clientSecretKey) { - - byte[] decryptedMessage = null; - //String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); - - //test source - //System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); - System.out.println("Base64 문자열: " + eaiStringBody); - System.out.println("Base64 문자열 길이: " + eaiStringBody.length()); - System.out.println("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); - - // Base64 디코딩 테스트 - try { - byte[] decoded = Base64.getDecoder().decode(eaiStringBody); - System.out.println("디코딩 성공, 길이: " + decoded.length); - } catch (IllegalArgumentException e) { - System.out.println("Base64 디코딩 실패: " + e.getMessage()); - } - // end test source - - switch (decryptAlgorithm) { - case "AES128": - - String key128 = clientSecretKey.substring(22,38); //togetherEncoder 경우는 substring(44,60) 이네?? - try { - //String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); - String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); - } - break; - case "AES256": - String key = clientSecretKey.substring(10,42); - try { - String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); - decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); - } - break; - default: - try { - //decryptedMessage = Arrays.copyOf(eaiBody, eaiBody.length); - decryptedMessage = eaiStringBody.getBytes(); - } catch (Exception e) { - e.printStackTrace(); - logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); - } - break; - } - - return decryptedMessage; - } - - // jwhong until here - - - private Map assignParameterMap(HttpServletRequest request, String adptGrpName, String adptName, - Object requestBytes, Properties prop) { - // PathVariable 체크 - if (StringUtils.equalsAnyIgnoreCase(request.getMethod(), HttpMethod.GET.name(), HttpMethod.DELETE.name()) - && StringUtils.isBlank(request.getQueryString())) { - try { - String actionName = prop.getProperty(Processor.REQUEST_ACTION); - RequestAction action = ActionFactory.createAction(actionName); - action.setAdapterInfo(adptGrpName, adptName, prop); - String[] keys = action.perform(requestBytes); - String requestPath = keys[0]; - - // PathVariable 지원 추가 - String ruledPath = StandardMessageUtil.getMatchedKey(requestPath, actionName); - if (!StringUtils.equals(requestPath, ruledPath) && StringUtils.contains(ruledPath, "{")) { - Map paramMap = new AntPathMatcher().extractUriTemplateVariables(ruledPath, - requestPath); - if (paramMap != null && paramMap.size() > 0) { - Map returnMap = new HashMap<>(); - for (String key : paramMap.keySet()) { - if (StringUtils.equalsIgnoreCase(key, "method")) { - continue; - } - returnMap.put(key, new String[] { paramMap.get(key) }); - } - - return returnMap; - } - } - } catch (Exception e) { - logger.error(e.getMessage()); - } - } - - return request.getParameterMap(); - } - - private Properties getHeaders(HttpServletRequest request) { - Properties prop = new Properties(); - - Enumeration headerNames = request.getHeaderNames(); - while (headerNames.hasMoreElements()) { - String key = headerNames.nextElement(); - String value = request.getHeader(key); - prop.setProperty(key, value); - } - - return prop; - } - - private String getExtUri(HttpServletRequest request) { - String orgUri = request.getRequestURI().replaceAll(request.getContextPath(), ""); - String uri = getExtUri(orgUri, 3); - if (uri != null && uri.trim().length() > 0) { - return "/" + uri; - } else { - return ""; - } - } - - private static String getExtUri(String url, int length) { - String[] urls = url.split("/"); - List newUrls = new ArrayList<>(); - Collections.addAll(newUrls, urls); - return StringUtils.join(newUrls.subList(length, urls.length).toArray(), "/"); - } - - @Override - @Deprecated - public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { - - } - - /** - * HTTP 요청에서 클라이언트 IP를 추출합니다. - * X-Forwarded-For 헤더가 있는 경우 이를 우선적으로 사용하고, - * 없는 경우 remoteAddr을 사용합니다. - */ - private String getClientIp(HttpServletRequest request) { - String ipAddress = request.getHeader("X-Forwarded-For"); - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("WL-Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("HTTP_CLIENT_IP"); - } - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR"); - } - if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getRemoteAddr(); - } - return ipAddress; - } -} +package com.eactive.eai.adapter.service; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpMethodType; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthFilter; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.inbound.action.ActionFactory; +import com.eactive.eai.inbound.action.RequestAction; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessageUtil; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.apache.mina.common.ByteBuffer; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.json.simple.parser.JSONParser; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.util.AntPathMatcher; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; +import java.util.*; + +//for encrypt/decrypt jwhong +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.kjbank.encrypt.exchange.crypto.AES256Cipher; +import com.kjbank.encrypt.exchange.crypto.AESCipher; +import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; +import java.nio.charset.StandardCharsets; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import org.springframework.security.oauth2.provider.ClientDetails; +import com.nimbusds.jwt.SignedJWT; + + +@Service +public class ApiAdapterService extends HttpAdapterServiceSupport { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String HEADER_GROUP = "HEADER_GROUP"; + public static final String HTTP_STATUS = "HTTP_STATUS"; // jwhong + // HEADER_GROUP JSON에 추가할 항목 정의, 없으면 전체 header 추가 + public static final String HEADER_KEYS = "HEADER_KEYS"; + public static final String PROPERTIES_NAME_HTTP_REQUEST_METHOD = "httpRequestMethod"; + + private static final String JSON_CONTENT_TYPE = "application/json"; + private static final String JSON_FIELD_NAME = "json-body"; + private static final String FILE_GROUP_NAME = "image-file"; + private static final String UPLOAD_ROOT_PATH = "UPLOAD_ROOT_PATH"; + public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong + + public String callApi(HttpServletRequest request, HttpServletResponse response, Properties httpProp, AdapterGroupVO adapterGroupVO, AdapterVO adapterVO, Properties transactionProp) throws Exception { + int traceLevel = 0; + + AdapterPropManager manager = null; + String adptGrpName = adapterGroupVO.getName(); + String adptName = adapterVO.getName(); + + + String urlDecodeYn = httpProp.getProperty(URL_DECODE_YN, "N"); + String encode = StringUtils.defaultIfBlank(adapterGroupVO.getMessageEncode(), "UTF-8"); + + String traceLevelTemp = httpProp.getProperty(TRACE_LEVEL, "0"); + String relayRequestHeaderKeys = httpProp.getProperty(HEADER_KEYS); + String headerGroupName = httpProp.getProperty(HEADER_GROUP); + + boolean isParameterType = false; + String message = null; + + String paramValue = null; + String adptMsgType = null; + + transactionProp.put(INBOUND_METHOD, request.getMethod()); + transactionProp.put(INBOUND_URI, request.getRequestURI()); + transactionProp.put(INBOUND_HEADER, getHeaders(request)); + if (StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) + || StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { + // /api/v1/public/getUserInfo.svc + String extUrl = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); + transactionProp.put(INBOUND_EXTURI, extUrl); + } else { + transactionProp.put(INBOUND_EXTURI, getExtUri(request)); + } + transactionProp.put(INBOUND_CLIENT_IP, getClientIp(request)); // Client IP 추가 + transactionProp.put(Processor.REQUEST_ACTION, adapterVO.getAdapterGroupVO().getRefClass()); + transactionProp.put(API_PATH, httpProp.getProperty(API_PATH, "")); + transactionProp.put(PRE_FILTERS, httpProp.getProperty(PRE_FILTERS, "")); + transactionProp.put(POST_FILTERS, httpProp.getProperty(POST_FILTERS, "")); + transactionProp.put(PROPERTIES_NAME_HTTP_REQUEST_METHOD, request.getMethod()); + transactionProp.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); + + transactionProp.put(ENC_PATHS, httpProp.getProperty(ENC_PATHS, "")); + + transactionProp.put(ENCRYPT_ALGORITHM, httpProp.getProperty(ENCRYPT_ALGORITHM, "")); //jwhong + if (getHeaders(request).get(HEADER_NAME_CLIENT_ID) != null) { // jwhong + transactionProp.put(HEADER_NAME_CLIENT_ID, getHeaders(request).get(HEADER_NAME_CLIENT_ID)); + } + transactionProp.put(ENCRYPT_BASE_TYPE, httpProp.getProperty(ENCRYPT_BASE_TYPE, "")); //jwhong + //transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN)); // jwhong + transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN) != null ? getHeaders(request).get(INBOUND_TOKEN) : ""); //jwhong , null 이면 default로 "" put + transactionProp.put(ENCRYPT_AES256_IV, httpProp.getProperty(ENCRYPT_AES256_IV, "")); //jwhong + transactionProp.put(ENCRYPT_AES256_KEY, httpProp.getProperty(ENCRYPT_AES256_KEY, "")); //jwhong + + + try { + traceLevel = Integer.parseInt(traceLevelTemp); + } catch (Exception e) { + traceLevel = 0; + } + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + logger.debug("시작 >> encode = [" + encode + "]"); + + switch (HttpMethodType.getValue(request.getMethod())) { + case GET: + case DELETE: + isParameterType = true; + break; + case POST: + case PUT: + if (StringUtils.contains(request.getContentType(), "application/x-www-form-urlencoded")) { + isParameterType = true; + } else { + isParameterType = false; + } + break; + default: + break; + } + + if (isParameterType) { + paramValue = request.getQueryString(); + if (paramValue == null) + paramValue = ""; + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "RECV " + "[" + paramValue + "]" + CommonLib.getDumpMessage(paramValue)); + } + + // json으로 변환 + StringBuilder sb = new StringBuilder(); + sb.append("{"); + Map paramMap = assignParameterMap(request, adptGrpName, adptName, null, transactionProp); + int i = 0; + for (Map.Entry entry : paramMap.entrySet()) { + if (i > 0) { + sb.append(","); + } + sb.append("\"").append(entry.getKey()).append("\":"); + String[] values = entry.getValue(); + if (values.length > 1) { + // ["111", "222"] + sb.append("["); + for (int j = 0; j < values.length; j++) { + if (j > 0) { + sb.append(","); + } + sb.append("\"").append(JSONValue.escape(values[j])).append("\""); + } + sb.append("]"); + } else { + sb.append("\"").append(JSONValue.escape(values[0])).append("\""); + } + + i++; + } + + sb.append("}"); + + paramValue = sb.toString(); + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceRest] RECV (" + adptGrpName + ") = [" + paramValue + "]\n" + + CommonLib.getDumpMessage(paramValue.getBytes(encode))); + } + } else { + ServletInputStream sis = request.getInputStream(); + ByteBuffer bb = ByteBuffer.allocate(1024).setAutoExpand(true); + int i = 0; + byte[] cbuf = new byte[1024]; + while ((i = sis.read(cbuf, 0, 1024)) != -1) { + if (i == 1024) { + bb.put(cbuf); + } else { + byte[] tail = new byte[i]; + System.arraycopy(cbuf, 0, tail, 0, i); + bb.put(tail); + } + } + byte[] data = new byte[bb.position()]; + bb.position(0); + bb.get(data); + paramValue = new String(data, encode); + + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "RECV " + "[" + paramValue + "]" + CommonLib.getDumpMessage(data)); + } + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceRest] RECV (" + adptGrpName + ") = [" + paramValue + "]\n" + + CommonLib.getDumpMessage(data)); + } + } + + if (paramValue == null) { // parameter가 없는 경우때문에 처리 + paramValue = ""; + } + else { // jwhong decrypt + paramValue = doPreDecryption(paramValue, transactionProp, request); + } + + if ("Y".equals(urlDecodeYn) && isParameterType) { + message = URLDecoder.decode(paramValue); + } else { + message = paramValue; + } + + if (logger.isDebug()) { + String[] msgArgs = new String[2]; + msgArgs[0] = adptGrpName; + msgArgs[1] = message; + String resMsg = ExceptionUtil.make("RICEAIAHA005", msgArgs); + logger.debug(resMsg); + } + + + adptMsgType = adapterVO.getAdapterGroupVO().getMessageType(); +// HttpHeaders responseHeaders = new HttpHeaders(); +// responseHeaders.setContentType(MediaType.valueOf("application/json;charset=" + encode)); + + + // HEADER_GROUP 셋팅 + if (MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName) + && StringUtils.isNotBlank(relayRequestHeaderKeys)) { + JSONObject jsonMessage = (JSONObject) JSONValue.parse(message); + JSONObject headerJson = new JSONObject(); + if (StringUtils.equalsIgnoreCase(relayRequestHeaderKeys, "ALL")) { + for (Enumeration e = request.getHeaderNames(); e.hasMoreElements(); ) { + String key = e.nextElement(); + headerJson.put(key, request.getHeader(key)); + } + } else { + String[] relayKeyArr = org.springframework.util.StringUtils + .tokenizeToStringArray(relayRequestHeaderKeys, ","); + + for (String key : relayKeyArr) { + String headerValue = request.getHeader(key); + if (StringUtils.isNotBlank(headerValue)) { + headerJson.put(key, headerValue); + } + } + } + + if (headerJson.size() > 0) { + jsonMessage.put(headerGroupName, headerJson); + message = jsonMessage.toJSONString(); + } + } + + if (message == null) { + message = ""; + } + + transactionProp.put(INBOUND_REQUEST_MESSAGE, message); + // 로컬 서비스 호출 ,encoding 처리 추가 + String result = (String) service(adptGrpName, adptName, message, transactionProp, request, response); + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceRest] result " + encode + " (" + adptGrpName + ") = [" + result + "]"); + } + + stopWatch.stop(); + + String syncAsyncType = transactionProp.getProperty(INBOUND_SYNC_ASYNC_TYPE); + + if (!"ASYN".equals(syncAsyncType) && MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName)) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode rootNode = (ObjectNode) mapper.readTree(result); + JsonNode headerGroup = rootNode.get(headerGroupName); + if(headerGroup != null) { + for(Iterator it = headerGroup.fieldNames(); it.hasNext();) { + String name = it.next(); + String value = headerGroup.get(name).asText(); + response.addHeader(name, value); + } + rootNode.remove(headerGroupName); + result = mapper.writeValueAsString(rootNode); + } + } + + // KJBank는 요청에 대한 응답 (Sync응답, Aync 에 대한 Ack응답) 에 대하여 암호화 하지 않는다. 무조건 안한다. 따라서 아래부분은 구현은 했지만 사용하지 않는다. + //result = doPostEncryption(result, transactionProp); // jwhong Encrypt + return result; + } + + + // jwhong decrypt + + private String doPreDecryption(String eaiBody, Properties transactionProp, HttpServletRequest request) { + String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, ""); + String xElinkClientId = transactionProp.getProperty(HEADER_NAME_CLIENT_ID, ""); // 이 값이 OAuth의 client id 값이다 . http header 에 포함되어 온다. jwhong + String encryptBaseKeyType = transactionProp.getProperty(ENCRYPT_BASE_TYPE); + //String inboundToken2 = transactionProp.getProperty(INBOUND_TOKEN, ""); // 이건 token 값이 아니고 authorization 값이다 + String inboundToken = ""; + + String secretAES256Iv = transactionProp.getProperty("ENCRYPT_AES256_IV"); + String secretAES256Key = transactionProp.getProperty("ENCRYPT_AES256_KEY"); + + if ( decryptAlgorithm == "" ) { // 복호화 대상이 아님 + return eaiBody; + } + + inboundToken = JwtTokenExtractor(request); + xElinkClientId = JwtClientIdExtractor(inboundToken); // token에서 client id를 추출함 + + // 암호화 key를 token 내용으로 할지 client secret 내용으로 할지 결정함. adapter property에 정의함 + // ENCRYPT_ALGORITHM 을 설정했는데 ENCRYPT_BASE_TYPE을 설정안하면 Decrypt 수행시 Exception 발생함 + String clientSecret = ""; + if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { + clientSecret = inboundToken; + } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(xElinkClientId); + + if ( clientDetail != null ) { // 여기서 not null 이라는 것은 apim oauth server에서 발급된 token 임. + // 즉 KJBank 에서 요청이 들어온 것이다. + clientSecret = clientDetail.getClientSecret(); + } // 그럼 업체에서 요청이 들어오면?? 업체도 apim oauth server에서 발급된 token을 사용하는것이다. + } + + byte[] decryptedMessage = null; + decryptedMessage = doInboundPreDecrypt(eaiBody, decryptAlgorithm,clientSecret,secretAES256Iv, secretAES256Key ); + + String resultMessage = new String(decryptedMessage, StandardCharsets.UTF_8 ); + return resultMessage; + //return new String(decryptedMessage, StandardCharsets.UTF_8 ); + } + + + // jwhong encrypt + private String doPostEncryption(String eaiBody, Properties transactionProp) { + String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, ""); + String xElinkClientId = transactionProp.getProperty(HEADER_NAME_CLIENT_ID, ""); // 이 값이 OAuth의 client id 값이다 . http header 에 포함되어 온다. jwhong + String encryptBaseKeyType = transactionProp.getProperty(ENCRYPT_BASE_TYPE); + String inboundToken = transactionProp.getProperty(INBOUND_TOKEN, ""); + + String secretAES256Iv = transactionProp.getProperty("ENCRYPT_AES256_IV"); + String secretAES256Key = transactionProp.getProperty("ENCRYPT_AES256_KEY"); + + + if ( decryptAlgorithm == "" ) { // 복호화 대상이 아님 + return eaiBody; + } + + // 암호화 key를 token 내용으로 할지 client secret 내용으로 할지 결정함. adapter property에 정의함 + // ENCRYPT_ALGORITHM 을 설정했는데 ENCRYPT_BASE_TYPE을 설정안하면 Decrypt 수행시 Exception 발생함 + String clientSecret = ""; + if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) { + clientSecret = inboundToken; + } else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) { + OAuth2Manager manager = OAuth2Manager.getInstance(); + ClientDetails clientDetail = manager.getClientDeatilsStore().get(xElinkClientId); + + if ( clientDetail != null ) { + clientSecret = clientDetail.getClientSecret(); + } + } + + byte[] decryptedMessage = null; + decryptedMessage = doInboundPostEncrypt(eaiBody, decryptAlgorithm,clientSecret,secretAES256Iv, secretAES256Key ); + + String resultMessage = new String(decryptedMessage, StandardCharsets.UTF_8 ); + return resultMessage; + //return new String(decryptedMessage, StandardCharsets.UTF_8 ); + } + + + private byte[] convertObjectToBytes(Object obj) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + oos.flush(); + return bos.toByteArray(); + } + + private byte[] convertObjectToBase64Bytes(Object obj) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + oos.flush(); + oos.close(); + + // 직렬화된 byte[] → Base64 문자열 → 다시 byte[]로 변환 + String base64String = Base64.getEncoder().encodeToString(bos.toByteArray()); + return base64String.getBytes(StandardCharsets.UTF_8); + } + + public static Object convertBytesToObject(byte[] bytes) throws IOException, ClassNotFoundException { + try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bis)) { + return ois.readObject(); + } + } + + + private byte[] doInboundPreDecrypt(String eaiStringBody, String decryptAlgorithm, String clientSecretKey, String secretAES256Iv, String secretAES256Key) { + + byte[] decryptedMessage = null; + //String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); + + eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody); + + //test source + //System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); + System.out.println("Base64 문자열: " + eaiStringBody); + System.out.println("Base64 문자열 길이: " + eaiStringBody.length()); + System.out.println("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + + // Base64 디코딩 테스트 + try { + byte[] decoded = Base64.getDecoder().decode(eaiStringBody); + System.out.println("디코딩 성공, 길이: " + decoded.length); + } catch (IllegalArgumentException e) { + System.out.println("Base64 디코딩 실패: " + e.getMessage()); + } + // end test source + + switch (decryptAlgorithm) { + case "AES128-TOSS": + try { + String key128 = clientSecretKey.substring(22,38); //togetherEncoder 경우는 substring(44,60) 이네?? + //String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); + String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES128-TOGETHER": + try { + String key128 = clientSecretKey.substring(44,60); //togetherEncoder 경우는 substring(44,60) 이네?? + //String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); + String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES256": + try { + String key = clientSecretKey.substring(10,42); + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + case "AES256-KAKAO": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, secretAES256Iv, secretAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, secretAES256Iv, secretAES256Key); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + + case "AES256GCM": + try { + byte[] key = AES256GCMCipher.generateKey(); + AES256GCMCipher cipher = new AES256GCMCipher(key); + byte[] aad = "metadata".getBytes(); + + String decryptedStrMessage = cipher.decrypt(eaiStringBody , aad); + decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; + default: + try { + decryptedMessage = eaiStringBody.getBytes(); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); + } + break; + } + + return decryptedMessage; + } + + private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) { + + String decryptedJsonKey = ""; + String decryptedBodyMessage = ""; + + switch (decryptAlgorithm) { + case "AES128-TOSS": + decryptedJsonKey = "preScreeningRequest"; + break; + case "AES128-TOGETHER": + decryptedJsonKey = "obpTxData"; + break; + case "AES256": + decryptedJsonKey = "preScreeningRequest"; + break; + case "AES256-KAKAO": + decryptedJsonKey = "encrypted_data"; + break; + case "AES256-TOSS": + decryptedJsonKey = "encryptedData"; + break; + case "AES256GCM": + break; + default: + break; + } + + try { + JSONParser parser = new JSONParser(); + JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody); + decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage()); + } + + return decryptedBodyMessage; + + } + + private byte[] doInboundPostEncrypt(String eaiStringBody, String encryptAlgorithm, String clientSecretKey, String secretAES256Iv, String secretAES256Key) { + + byte[] encryptedMessage = null; + //String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8); + + //test source + //System.out.println("eaiBody 바이트 배열 길이: " + eaiBody.length); + System.out.println("Base64 문자열: " + eaiStringBody); + System.out.println("Base64 문자열 길이: " + eaiStringBody.length()); + System.out.println("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); + + // Base64 디코딩 테스트 + try { + byte[] decoded = Base64.getDecoder().decode(eaiStringBody); + System.out.println("디코딩 성공, 길이: " + decoded.length); + } catch (IllegalArgumentException e) { + System.out.println("Base64 디코딩 실패: " + e.getMessage()); + } + // end test source + + switch (encryptAlgorithm) { + case "AES128-TOSS": + try { + String key128 = clientSecretKey.substring(22,38); //togetherEncoder 경우는 substring(44,60) 이네?? + String decryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128); + encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES128-TOGETHER": + try { + String key128 = clientSecretKey.substring(44,60); //togetherEncoder 경우는 substring(44,60) 이네?? + String decryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128); + encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage()); + } + break; + case "AES256": + try { + String key = clientSecretKey.substring(10,42); + String decryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, key); + encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + case "AES256-KAKAO": + try { + String decryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key); + encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + case "AES256-TOSS": + try { + String decryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key); + encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage()); + } + break; + + case "AES256GCM": + try { + byte[] key = AES256GCMCipher.generateKey(); + AES256GCMCipher cipher = new AES256GCMCipher(key); + byte[] aad = "metadata".getBytes(); + + String decryptedStrMessage = cipher.encrypt(eaiStringBody , aad); + encryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage()); + } + break; + default: + try { + encryptedMessage = eaiStringBody.getBytes(); + } catch (Exception e) { + e.printStackTrace(); + logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage()); + } + break; + } + + return encryptedMessage; + } + + + + private String JwtTokenExtractor(HttpServletRequest request) { + + String Token = ""; + try { + Token = JwtAuthFilter.extractJWTToken(request); + } catch (Exception e) { + logger.error(e.getMessage()); + } + + System.out.println("Token is: " + Token); + return Token; + + } + + private String JwtClientIdExtractor(String inboundToken) { + + String tokenClientId =""; + try { + SignedJWT signedJWT = SignedJWT.parse(inboundToken); + tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); + } catch (Exception e) { + logger.error(e.getMessage()); + tokenClientId = ""; + } + + System.out.println("Token Client ID: " + tokenClientId); + return tokenClientId; + + } + + // jwhong until here + + + private Map assignParameterMap(HttpServletRequest request, String adptGrpName, String adptName, + Object requestBytes, Properties prop) { + // PathVariable 체크 + if (StringUtils.equalsAnyIgnoreCase(request.getMethod(), HttpMethod.GET.name(), HttpMethod.DELETE.name()) + && StringUtils.isBlank(request.getQueryString())) { + try { + String actionName = prop.getProperty(Processor.REQUEST_ACTION); + RequestAction action = ActionFactory.createAction(actionName); + action.setAdapterInfo(adptGrpName, adptName, prop); + String[] keys = action.perform(requestBytes); + String requestPath = keys[0]; + + // PathVariable 지원 추가 + String ruledPath = StandardMessageUtil.getMatchedKey(requestPath, actionName); + if (!StringUtils.equals(requestPath, ruledPath) && StringUtils.contains(ruledPath, "{")) { + Map paramMap = new AntPathMatcher().extractUriTemplateVariables(ruledPath, + requestPath); + if (paramMap != null && paramMap.size() > 0) { + Map returnMap = new HashMap<>(); + for (String key : paramMap.keySet()) { + if (StringUtils.equalsIgnoreCase(key, "method")) { + continue; + } + returnMap.put(key, new String[] { paramMap.get(key) }); + } + + return returnMap; + } + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + + return request.getParameterMap(); + } + + private Properties getHeaders(HttpServletRequest request) { + Properties prop = new Properties(); + + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String key = headerNames.nextElement(); + String value = request.getHeader(key); + prop.setProperty(key, value); + } + + return prop; + } + + private String getExtUri(HttpServletRequest request) { + String orgUri = request.getRequestURI().replaceAll(request.getContextPath(), ""); + String uri = getExtUri(orgUri, 3); + if (uri != null && uri.trim().length() > 0) { + return "/" + uri; + } else { + return ""; + } + } + + private static String getExtUri(String url, int length) { + String[] urls = url.split("/"); + List newUrls = new ArrayList<>(); + Collections.addAll(newUrls, urls); + return StringUtils.join(newUrls.subList(length, urls.length).toArray(), "/"); + } + + @Override + @Deprecated + public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { + + } + + /** + * HTTP 요청에서 클라이언트 IP를 추출합니다. + * X-Forwarded-For 헤더가 있는 경우 이를 우선적으로 사용하고, + * 없는 경우 remoteAddr을 사용합니다. + */ + private String getClientIp(HttpServletRequest request) { + String ipAddress = request.getHeader("X-Forwarded-For"); + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_CLIENT_IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + } + return ipAddress; + } +}