feat: DJB ERP 연동 암복호화 필터 추가 및 단위테스트 작성
- DJBErpCryptoFilter: CryptoFilter 상속, httpHeaderGroup 헤더 JSON에서 x-emp-nm(groupSeq|empNo) 파싱 → groupSeq를 runtimeContext로 전달 - DJBErpCryptoFilterTest: 17개 단위테스트 (buildRuntimeContext/doPreFilter/doPostFilter) - elink-online-common 서브모듈 업데이트 (CryptoFilter 기반 클래스 포함) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+82
@@ -0,0 +1,82 @@
|
||||
package com.eactive.eai.custom.adapter.http.dynamic.filter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.eactive.eai.adapter.http.dynamic.filter.CryptoFilter;
|
||||
import com.eactive.eai.util.JsonPathUtil;
|
||||
|
||||
/**
|
||||
* DJB ERP 연동용 암복호화 필터.
|
||||
*
|
||||
* DYNAMIC 키 컨텍스트 추출 규칙:
|
||||
* HTTP 헤더 {@code httpHeaderGroup}의 값은 JSON 객체이며,
|
||||
* 그 중 {@code x-emp-nm} 필드 값을 {@code groupSeq}로
|
||||
* runtimeContext에 담아 키 도출 전략에 전달한다.
|
||||
*
|
||||
* 어댑터 프로퍼티 (부모 클래스 공통 설정 외 추가 키):
|
||||
* crypto.context.key runtimeContext에 넣을 키 이름 (기본: groupSeq)
|
||||
* crypto.context.header 컨텍스트 JSON이 담긴 HTTP 헤더명 (기본: httpHeaderGroup)
|
||||
* crypto.context.header.field 헤더 JSON에서 추출할 필드명 (기본: x-emp-nm)
|
||||
*
|
||||
* 어댑터 프로퍼티 설정 예:
|
||||
* crypto.module.name = AES_GCM_NoPadding_DYNAMIC_sample
|
||||
* crypto.scope = FIELD
|
||||
* crypto.dec.enabled = Y
|
||||
* crypto.enc.enabled = N
|
||||
* crypto.dec.from.path = /encryptedData
|
||||
* crypto.dec.to.path = /
|
||||
* crypto.context.key = groupSeq
|
||||
* crypto.context.header = httpHeaderGroup
|
||||
* crypto.context.header.field = x-emp-nm
|
||||
*
|
||||
* 필터 타입 등록 (FQCN):
|
||||
* com.eactive.eai.custom.adapter.http.dynamic.filter.DJBErpCryptoFilter
|
||||
*/
|
||||
public class DJBErpCryptoFilter extends CryptoFilter {
|
||||
|
||||
public static final String PROP_CONTEXT_KEY = "crypto.context.key";
|
||||
public static final String PROP_CONTEXT_HEADER = "crypto.context.header";
|
||||
public static final String PROP_CONTEXT_HEADER_FIELD = "crypto.context.header.field";
|
||||
|
||||
private static final String DEFAULT_CONTEXT_KEY = "groupSeq";
|
||||
private static final String DEFAULT_CONTEXT_HEADER = "httpHeaderGroup";
|
||||
private static final String DEFAULT_CONTEXT_HEADER_FIELD = "x-emp-nm";
|
||||
|
||||
/**
|
||||
* httpHeaderGroup 헤더(JSON)에서 x-emp-nm 값을 추출하여 groupSeq로 매핑한다.
|
||||
* 헤더가 없거나 필드를 찾을 수 없으면 빈 Map을 반환한다.
|
||||
*/
|
||||
@Override
|
||||
protected Map<String, String> buildRuntimeContext(Properties prop, HttpServletRequest request) {
|
||||
Map<String, String> ctx = new HashMap<>();
|
||||
|
||||
String contextKey = prop.getProperty(PROP_CONTEXT_KEY, DEFAULT_CONTEXT_KEY);
|
||||
String contextHeaderName = prop.getProperty(PROP_CONTEXT_HEADER, DEFAULT_CONTEXT_HEADER);
|
||||
String contextHeaderField = prop.getProperty(PROP_CONTEXT_HEADER_FIELD, DEFAULT_CONTEXT_HEADER_FIELD);
|
||||
|
||||
String headerJson = request.getHeader(contextHeaderName);
|
||||
if (StringUtils.isBlank(headerJson)) {
|
||||
logger.warn("DJBErpCryptoFilter] 컨텍스트 헤더 없음: " + contextHeaderName);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
String value = JsonPathUtil.getValueAtPath(headerJson, "/" + contextHeaderField);
|
||||
if (value == null) {
|
||||
logger.warn("DJBErpCryptoFilter] 헤더 JSON에서 필드 추출 실패: header="
|
||||
+ contextHeaderName + ", field=" + contextHeaderField);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
// x-emp-nm 값은 "groupSeq|empNo" 형태 — '|' 앞부분만 groupSeq로 사용
|
||||
String groupSeq = value.contains("|") ? value.substring(0, value.indexOf('|')) : value;
|
||||
ctx.put(contextKey, groupSeq);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user