From 6d33b69bed300ae91f42dab591bcd407026b4e26 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Wed, 8 Jul 2026 18:31:39 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8=20=EC=B0=A8?= =?UTF-8?q?=EB=8B=A8=20API=20=EC=B6=94=EA=B0=80:=20-=20`ClientBlockApiCont?= =?UTF-8?q?roller`=20=EC=8B=A0=EA=B7=9C=20=EC=83=9D=EC=84=B1=20=EB=B0=8F?= =?UTF-8?q?=20=EC=B0=A8=EB=8B=A8=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=20-=20`ClientManService`=EC=97=90=20=ED=81=B4=EB=9D=BC?= =?UTF-8?q?=EC=9D=B4=EC=96=B8=ED=8A=B8=20=EC=B0=A8=EB=8B=A8=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80=20-=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20=EC=9A=94=EC=B2=AD=20=EC=82=AD=EC=A0=9C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=9C=EB=B0=9C=20=ED=99=98=EA=B2=BD=20=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=20=EB=AC=B8=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onl/apim/approval/portalApprovalMan.jsp | 2 +- .../approval/PortalApprovalManService.java | 5 ++ .../authserver/ClientBlockApiController.java | 82 +++++++++++++++++++ .../authserver/client/ClientManService.java | 12 +++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/eactive/eai/rms/onl/apim/authserver/ClientBlockApiController.java diff --git a/WebContent/jsp/onl/apim/approval/portalApprovalMan.jsp b/WebContent/jsp/onl/apim/approval/portalApprovalMan.jsp index 728c902..d4c3757 100644 --- a/WebContent/jsp/onl/apim/approval/portalApprovalMan.jsp +++ b/WebContent/jsp/onl/apim/approval/portalApprovalMan.jsp @@ -194,7 +194,7 @@
승인 요청 목록승인 요청을 관리합니다.
- [주의] 선택 삭제 시 승인 요청과 승인자 이력이 DB에서 영구 삭제됩니다. + [주의] 삭제 기능은 개발(dev) 환경에서만 동작합니다. 선택 삭제 시 승인 요청과 승인자 이력이 DB에서 영구 삭제됩니다.
diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/approval/PortalApprovalManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/approval/PortalApprovalManService.java index 8ef8fbe..6aa080a 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/approval/PortalApprovalManService.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/approval/PortalApprovalManService.java @@ -26,6 +26,7 @@ import com.eactive.eai.rms.onl.apim.portalorg.PortalOrgManService; import com.eactive.eai.rms.onl.apim.portaluser.PortalUserManService; import com.eactive.eai.rms.onl.apim.portaluser.PortalUserUI; import com.eactive.eai.rms.common.acl.user.ui.UserUI; +import com.eactive.eai.common.util.SystemUtil; import com.eactive.eai.rms.onl.common.exception.BizException; import com.eactive.eai.rms.onl.transaction.apim.ApiInterfaceService; import com.eactive.eai.rms.onl.transaction.apim.mapping.ApiSpecUIMapper; @@ -359,6 +360,10 @@ public class PortalApprovalManService extends BaseService { } public boolean isHardDeleteEnabled() { + // 승인 요청 완전삭제는 dev(개발) 환경에서만 허용 + if (!SystemUtil.isDevServer()) { + return false; + } Map properties = portalPropertyService.getPortalPropertiesAsMap(PORTAL_PROPERTY_GROUP); return Boolean.parseBoolean(properties.getOrDefault(HARD_DELETE_FLAG_KEY, "false")); } diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/authserver/ClientBlockApiController.java b/src/main/java/com/eactive/eai/rms/onl/apim/authserver/ClientBlockApiController.java new file mode 100644 index 0000000..43dff86 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/onl/apim/authserver/ClientBlockApiController.java @@ -0,0 +1,82 @@ +package com.eactive.eai.rms.onl.apim.authserver; + +import com.eactive.eai.agent.command.CommonCommand; +import com.eactive.eai.rms.common.datasource.DataSourceContextHolder; +import com.eactive.eai.rms.common.datasource.DataSourceType; +import com.eactive.eai.rms.common.datasource.DataSourceTypeManager; +import com.eactive.eai.rms.onl.apim.common.BaseRestController; +import com.eactive.eai.rms.onl.common.service.AgentUtilService; +import com.eactive.eai.rms.onl.manage.authserver.client.ClientManService; +import java.util.HashMap; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * 포털 등 내부 시스템이 호출하는 인증서버(GW) 클라이언트 제어용 내부 API. + * + *

{@link BaseRestController} 를 상속하여 ① 세션 인증을 skip(InterceptorSkipController)하고 + * ② {@code IpWhitelistInterceptor} 를 통해 {@code kjb.api.allow_ip_list} 기준 IP 화이트리스트 + * 인증을 적용받는다. (호출 측 포털 서버 IP를 반드시 허용목록에 등록해야 함)

+ * + * @see com.eactive.eai.rms.common.interceptor.IpWhitelistInterceptor + */ +@Controller +public class ClientBlockApiController extends BaseRestController { + + private static final Logger logger = LoggerFactory.getLogger(ClientBlockApiController.class); + + private final ClientManService clientManService; + + @Qualifier("onlAgentUtilService") + @Autowired + private AgentUtilService agentUtilService; + + @Autowired + public ClientBlockApiController(ClientManService clientManService) { + this.clientManService = clientManService; + } + + /** + * clientId 의 GW 인증 클라이언트를 차단(TSEAIAU01.appstatus = '0')한 뒤, + * 승인 경로와 동일하게 GW 인증서버로 RELOAD_CLIENT 명령을 broadcast 하여 캐시를 갱신한다. + * + * @param clientId 차단할 클라이언트 ID + * @return 처리 결과 JSON ({@code {"success":true,"clientId":...}} 또는 {@code {"success":false,"msg":...}}) + */ + @RequestMapping(value = "/onl/admin/authserver/clientBlock.json", method = RequestMethod.POST, produces = JSON_CONTENT_TYPE) + @ResponseBody + public String blockClient(@RequestParam String clientId) { + Map result = new HashMap<>(); + try { + // TSEAIAU01(ClientEntity)은 APIGW 데이터소스에 있으므로 라우팅을 먼저 설정한다. + DataSourceType type = DataSourceTypeManager.getDataSourceType("APIGW"); + DataSourceContextHolder.setDataSourceType(type); + + // 상태 차단 (appstatus = '0') + clientManService.blockClient(clientId); + + // GW 인증서버 캐시 리로드 (승인 경로 PortalAppApprovalListener 와 동일) + CommonCommand.builder() + .name(CommonCommand.RELOAD_CLIENT_COMMAND) + .args(clientId) + .build().broadcast(agentUtilService); + + logger.warn("GW client 차단(appstatus=0)+리로드 완료 - clientId={}", clientId); + result.put("success", true); + result.put("clientId", clientId); + } catch (Exception e) { + logger.error("GW client 차단 실패 - clientId={}", clientId, e); + result.put("success", false); + result.put("msg", e.getMessage()); + } + return toJson(result); + } +} diff --git a/src/main/java/com/eactive/eai/rms/onl/manage/authserver/client/ClientManService.java b/src/main/java/com/eactive/eai/rms/onl/manage/authserver/client/ClientManService.java index 720e356..319a1e8 100644 --- a/src/main/java/com/eactive/eai/rms/onl/manage/authserver/client/ClientManService.java +++ b/src/main/java/com/eactive/eai/rms/onl/manage/authserver/client/ClientManService.java @@ -103,6 +103,18 @@ public class ClientManService extends OnlBaseService { clientEntityService.deleteById(clientId); } + /** + * 인증 클라이언트를 차단합니다. (appstatus = '0') + * 삭제하지 않고 상태만 차단으로 변경합니다. + * + * @param clientId 차단할 클라이언트 ID + */ + public void blockClient(String clientId) { + ClientEntity clientEntity = clientEntityService.getById(clientId); + clientEntity.setAppstatus("0"); // 0: 차단, 1: 정상 + clientEntityService.save(clientEntity); + } + public List findAll() { List clientList = clientEntityService.findAll();