암복호화 기능 수정
This commit is contained in:
+10
-13
@@ -81,6 +81,7 @@ import com.eactive.eai.common.util.TxFileLogger;
|
||||
import com.eactive.eai.common.util.XMLUtils;
|
||||
import com.eactive.eai.util.JsonPathUtil;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.jayway.jsonpath.DocumentContext;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
@@ -127,6 +128,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
|
||||
|
||||
private boolean useAdapterToken;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 1. 기능 : REST API 통신에 사용 <br>
|
||||
* 2. 처리 개요 : - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. <br>
|
||||
@@ -876,18 +879,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
|
||||
String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken()));
|
||||
}
|
||||
|
||||
/* nice on 나이스 지키미 용으로 생성함
|
||||
* jwhong 2015-11-04
|
||||
*/
|
||||
private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception {
|
||||
method.setHeader("Authorization",
|
||||
String.format("%s %s", "bearer", auth)); // 나이스지키미 format임, bearer을 소문자로 보내야함
|
||||
String productId = PropManager.getInstance().getProperty("NiceOnProperty","productId.value");
|
||||
method.setHeader("ProductID", productId);
|
||||
//method.setHeader("Authorization",
|
||||
// String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken()));
|
||||
}
|
||||
|
||||
private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues,
|
||||
String encode) {
|
||||
if (responseMessage == null) {
|
||||
@@ -923,12 +914,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
|
||||
if ( httpHeader instanceof ObjectNode) {
|
||||
ObjectNode objectNode = (ObjectNode) httpHeader;
|
||||
objectNode.fields().forEachRemaining(e -> {
|
||||
if ("Content-Length".equalsIgnoreCase(e.getKey()))
|
||||
return;
|
||||
JsonNode value = e.getValue();
|
||||
method.setHeader((String) e.getKey(), value.isNull() ? null : value.asText());
|
||||
});
|
||||
} else if (httpHeader instanceof JSONObject) {
|
||||
JSONObject jsonObject = (JSONObject) httpHeader;
|
||||
for (Object key : jsonObject.keySet()) {
|
||||
if ("Content-Length".equalsIgnoreCase((String) key))
|
||||
continue;
|
||||
|
||||
Object obj = jsonObject.get(key);
|
||||
if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) {
|
||||
continue;
|
||||
@@ -939,7 +935,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1046,6 +1041,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp
|
||||
body = ((Document)eaiBody).asXML();
|
||||
} else if(eaiBody instanceof JSONObject) {
|
||||
body = ((JSONObject)eaiBody).toJSONString();
|
||||
} else if(eaiBody instanceof ObjectNode) {
|
||||
body = mapper.writeValueAsString((ObjectNode) eaiBody);
|
||||
} else {
|
||||
body = eaiBody.toString();
|
||||
}
|
||||
|
||||
+8
-2
@@ -9,6 +9,9 @@ import org.json.simple.JSONObject;
|
||||
import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
|
||||
import com.eactive.eai.adapter.http.client.impl.filter.HttpClient5AdapterFilterFactory;
|
||||
import com.eactive.eai.adapter.http.client.impl.filter.HttpClientAdapterFilter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
/**
|
||||
* 1. 기능 : HttpClient5AdapterServiceRest 호출 전후 Filter 적용할 수 있는 기능을 제공한다.<br>
|
||||
@@ -34,6 +37,8 @@ public class HttpClient5AdapterServiceRestAddFilter extends HttpClient5AdapterSe
|
||||
// // Adapter에서 Exception이 발생한 경우, 처리할 필터
|
||||
// static final String EXCEPTION_FILTER = "EXCEPTION_FILTER";
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 1. 기능 : HttpClient 호출 전후 Filter 적용용 2. 처리 개요 : <br>
|
||||
* 3. 주의사항 <br>
|
||||
@@ -54,8 +59,9 @@ public class HttpClient5AdapterServiceRestAddFilter extends HttpClient5AdapterSe
|
||||
adapterResponse = doPostFilters(adptGrpName, adptName, prop, adapterResponse, tempProp);
|
||||
if (adapterResponse instanceof JSONObject)
|
||||
adapterResponse = ((JSONObject) adapterResponse).toJSONString();
|
||||
|
||||
if (adapterResponse instanceof Node)
|
||||
else if (adapterResponse instanceof ObjectNode)
|
||||
adapterResponse = mapper.writeValueAsString((ObjectNode) adapterResponse);
|
||||
else if (adapterResponse instanceof Node)
|
||||
adapterResponse = ((Node) adapterResponse).asXML();
|
||||
|
||||
return adapterResponse;
|
||||
|
||||
@@ -31,7 +31,15 @@ public class OutCryptoFilter extends AbstractCryptoFilter implements HttpClientA
|
||||
* 서브클래스에서 오버라이드하여 tempProp으로부터 값을 추출할 수 있다.
|
||||
*/
|
||||
protected Map<String, String> buildRuntimeContext(Properties prop, Properties tempProp) {
|
||||
return new HashMap<>();
|
||||
Map<String, String> context = new HashMap<>();
|
||||
for (String key : prop.stringPropertyNames()) {
|
||||
context.put(key, prop.getProperty(key));
|
||||
}
|
||||
|
||||
for (String key : tempProp.stringPropertyNames()) {
|
||||
context.put(key, tempProp.getProperty(key));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,11 +47,10 @@ public class OutCryptoFilter extends AbstractCryptoFilter implements HttpClientA
|
||||
* 미설정 또는 값 없으면 null을 반환하여 GCM 기본 동작(IV를 AAD 대체값으로 사용)을 따른다.
|
||||
*/
|
||||
protected byte[] buildAad(Properties prop, Properties tempProp) {
|
||||
String propKey = prop.getProperty(PROP_AAD_HEADER);
|
||||
if (StringUtils.isBlank(propKey) || tempProp == null) {
|
||||
return null;
|
||||
}
|
||||
String value = tempProp.getProperty(propKey);
|
||||
if (tempProp == null) {
|
||||
return null;
|
||||
}
|
||||
String value = tempProp.getProperty(PROP_AAD_HEADER);
|
||||
return StringUtils.isBlank(value) ? null : value.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.MDC;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.eactive.eai.adapter.AdapterGroupVO;
|
||||
import com.eactive.eai.adapter.AdapterManager;
|
||||
@@ -21,6 +21,8 @@ import com.eactive.eai.common.TransactionContextKeys;
|
||||
import com.eactive.eai.common.util.Logger;
|
||||
import com.eactive.eai.common.util.TxSiftContext;
|
||||
import com.eactive.eai.common.util.UUIDGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public abstract class HttpAdapterServiceSupport implements HttpAdapterService, HttpAdapterServiceKey {
|
||||
private static final String LOG_PREFIX = "HttpAdapterServiceSupport] ";
|
||||
@@ -28,7 +30,8 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H
|
||||
public static final String HEADER_NAME_CLIENT_ID = "x-elink-client-id";
|
||||
public static final String PROPERTIES_NAME_CLIENT_ID = "clientId";
|
||||
static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public Object service(String adptGrpName, String adptName, Object message, Properties prop,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
String uuid = prop.getProperty(TransactionContextKeys.TRANSACTION_UUID);
|
||||
@@ -63,6 +66,13 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H
|
||||
Object obj = null;
|
||||
try {
|
||||
message = doPreFilters(adptGrpName, adptName, message, prop, request, response);
|
||||
|
||||
if (message instanceof JSONObject) {
|
||||
message = ((JSONObject) message).toJSONString();
|
||||
} else if (message instanceof JsonNode) {
|
||||
message = mapper.writeValueAsString((JsonNode) message);
|
||||
}
|
||||
|
||||
obj = RequestDispatcher.getRequestDispatcher(adptGrpName).handle(adptName, message, prop);
|
||||
obj = doPostFilters(adptGrpName, adptName, obj, prop, request, response);
|
||||
} catch (HttpStatusException e) { // inbound error
|
||||
@@ -86,6 +96,10 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H
|
||||
return (byte[]) obj;
|
||||
} else if (obj instanceof String) {
|
||||
return (String) obj;
|
||||
} else if (obj instanceof JSONObject) {
|
||||
return ((JSONObject) obj).toJSONString();
|
||||
} else if (obj instanceof JsonNode) {
|
||||
return mapper.writeValueAsString((JsonNode) obj);
|
||||
} else {
|
||||
throw new Exception("RECEAIAHA001");
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@ import com.eactive.eai.adapter.http.filter.AbstractCryptoFilter;
|
||||
*/
|
||||
public class InCryptoFilter extends AbstractCryptoFilter implements HttpAdapterFilter {
|
||||
|
||||
/**
|
||||
public static final String ERROR_DEC_FAIL = "E.DECRYPT_FAIL";
|
||||
public static final String ERROR_ENC_FAIL = "E.ENCRYPT_FAIL";
|
||||
/**
|
||||
* DYNAMIC 키 도출용 컨텍스트를 구성한다.
|
||||
* STATIC 키 모듈이면 빈 Map({@code new HashMap<>()})을 반환한다.
|
||||
* 서브클래스에서 오버라이드하여 HttpServletRequest로부터 값을 추출할 수 있다.
|
||||
|
||||
@@ -66,7 +66,7 @@ public abstract class AbstractCryptoFilter {
|
||||
* fromPath의 Base64 값을 복호화하여 toPath에 반영. JSON 파싱 1회.
|
||||
* toPath = "/" → fromPath 필드를 제거하고 복호화된 JSON을 body에 병합.
|
||||
*/
|
||||
protected String decryptField(String body, String moduleName, Map<String, String> runtimeCtx,
|
||||
protected Object decryptField(String body, String moduleName, Map<String, String> runtimeCtx,
|
||||
byte[] aad, String fromPath, String toPath) throws Exception {
|
||||
JsonNode root = JsonPathUtil.toTree(body);
|
||||
String encBase64 = JsonPathUtil.getAt(root, fromPath);
|
||||
@@ -81,7 +81,7 @@ public abstract class AbstractCryptoFilter {
|
||||
return JsonPathUtil.mergeAtRoot(root, fromPath, plainText);
|
||||
}
|
||||
JsonPathUtil.setAt(root, toPath, plainText);
|
||||
return JsonPathUtil.fromTree(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@@ -99,7 +99,7 @@ public abstract class AbstractCryptoFilter {
|
||||
* fromPath 값을 암호화하여 toPath(Base64)에 반영. JSON 파싱 1회.
|
||||
* fromPath = "/" → body 전체를 암호화하여 toPath 필드명으로 래핑 (파싱 불필요).
|
||||
*/
|
||||
protected String encryptField(String body, String moduleName, Map<String, String> runtimeCtx,
|
||||
protected Object encryptField(String body, String moduleName, Map<String, String> runtimeCtx,
|
||||
byte[] aad, String fromPath, String toPath) throws Exception {
|
||||
if (PATH_ROOT.equals(fromPath)) {
|
||||
byte[] cipherBytes = CryptoModuleService.getInstance().encrypt(moduleName, runtimeCtx, aad,
|
||||
@@ -112,13 +112,13 @@ public abstract class AbstractCryptoFilter {
|
||||
String plainText = JsonPathUtil.getAt(root, fromPath);
|
||||
if (StringUtils.isBlank(plainText)) {
|
||||
logger.warn("CryptoFilter] 암호화 대상 필드 없음: path=" + fromPath);
|
||||
return body;
|
||||
return root;
|
||||
}
|
||||
byte[] cipherBytes = CryptoModuleService.getInstance().encrypt(moduleName, runtimeCtx, aad,
|
||||
plainText.getBytes(StandardCharsets.UTF_8));
|
||||
String encBase64 = Base64.getEncoder().encodeToString(cipherBytes);
|
||||
JsonPathUtil.setAt(root, toPath, encBase64);
|
||||
return JsonPathUtil.fromTree(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
@@ -145,12 +145,12 @@ public class JsonPathUtil {
|
||||
* @param mergeJson 병합할 JSON 문자열
|
||||
* @return 병합된 JSON 문자열, 병합 불가 시 mergeJson 그대로 반환
|
||||
*/
|
||||
public static String mergeAtRoot(JsonNode bodyNode, String removeFromPath, String mergeJson) {
|
||||
public static JsonNode mergeAtRoot(JsonNode bodyNode, String removeFromPath, String mergeJson) {
|
||||
try {
|
||||
JsonNode mergeNode = objectMapper.readTree(mergeJson);
|
||||
|
||||
if (!bodyNode.isObject() || !mergeNode.isObject()) {
|
||||
return mergeJson;
|
||||
return bodyNode;
|
||||
}
|
||||
|
||||
ObjectNode result = (ObjectNode) bodyNode.deepCopy();
|
||||
@@ -169,9 +169,10 @@ public class JsonPathUtil {
|
||||
|
||||
// mergeJson 필드를 body에 병합 (기존 필드 덮어쓰기)
|
||||
result.setAll((ObjectNode) mergeNode);
|
||||
return objectMapper.writeValueAsString(result);
|
||||
// return objectMapper.writeValueAsString(result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return mergeJson;
|
||||
return bodyNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +193,7 @@ public class JsonPathUtil {
|
||||
*/
|
||||
public static String mergeAtRoot(String body, String removeFromPath, String mergeJson) {
|
||||
try {
|
||||
return mergeAtRoot(objectMapper.readTree(body), removeFromPath, mergeJson);
|
||||
return objectMapper.writeValueAsString(mergeAtRoot(objectMapper.readTree(body), removeFromPath, mergeJson));
|
||||
} catch (Exception e) {
|
||||
return mergeJson;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user