arko_renual/src/main/resources/egovframework/spring/com/context-syslogaop.xml
infraurp f2029a00a0 개인정보보호 기능개선 2차 구현 — 접속기록 안정화·솔트 인증·관리자 화면 4종
접속기록(SFR-004/#33):
- AccessLogQueue 포화 방어. 종전 offer(timeout) 무한 반복은 컨슈머 정지 시
  요청 스레드가 영구 대기해 WAS 스레드 풀 고갈 → 사이트 전면 정지로 이어졌다.
  대기를 3회로 제한하고 포화 차단기(saturated)를 도입해 지속 포화 시 즉시 판정한다.
- 유실은 조용히 넘기지 않는다. recordDrop 이 누적 집계 + 초기 20건/이후 100건 표본
  ERROR 로그로 남긴다(법정 보관 대상이므로 사후 추적 가능해야 함).
- 컨슈머 루프가 Exception 이 아닌 Throwable 까지 흡수한다. Error 하나로 컨슈머가
  죽으면 running=true 인 채 이후 전 요청이 포화 대기에 빠졌다.
- 자체 데몬 워치독(30초) 추가 — 컨슈머 사망 시 재기동, 적체 경고, 차단기 자동 해제.
  task:annotation-driven 활성화 여부와 무관해야 하므로 @Scheduled 를 쓰지 않는다.
- 해시체인 순번 보장을 위한 단일 컨슈머 전제는 유지(병렬화 금지).

인증정보 보호(SER-001/SER-003/#27):
- EgovFileScrty 사용자별 랜덤 솔트(S1: 형식) 도입, matches() 로 검증 일원화 —
  기존 무솔트 계정과 공존한다.
- 비밀번호 변경 시 현재 비밀번호 검증 복구. 종전에는 DB 값을 자기 자신과 비교해
  항상 true 였고, 입력한 oldPassword 가 어디에도 쓰이지 않았다.
- 평문 비밀번호 println 제거.

관리자 화면: 접속기록 조회, 업무구분 매핑 관리, 권한변경 이력, 미사용계정 현황.
계정 파기(AccountDelete) 서비스 및 DDL/DML 추가.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 15:05:03 +09:00

91 lines
7.3 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- System Log Aspect -->
<bean id="syslog" class="egovframework.com.sym.log.lgm.service.EgovSysLogAspect" />
<!-- <aop:config>
<aop:aspect id="sysLogAspect" ref="syslog">
insert로 시작되는 service Method
<aop:around pointcut="execution(public * egovframework.com..impl.*Impl.insert*(..)) or
execution(public * kr.or.arko..impl.*Impl.insert*(..))" method="logInsert" />
update로 시작되는 service Method
<aop:around pointcut="execution(public * egovframework.com..impl.*Impl.update*(..)) or
execution(public * kr.or.arko..impl.*Impl.update*(..))" method="logUpdate" />
delete로 시작되는 service Method
<aop:around pointcut="execution(public * egovframework.com..impl.*Impl.delete*(..)) or
execution(public * kr.or.arko..impl.*Impl.delete*(..))" method="logDelete" />
select로 시작되는 service Method
<aop:around pointcut="execution(public * egovframework.com..impl.*Impl.select*(..)) or
execution(public * kr.or.arko..impl.*Impl.select*(..))" method="logSelect" />
</aop:aspect>
</aop:config> -->
<!-- =========================================================================
[이력 / 2026-08-07 중단] 아래 설명과 <aop:config> 는 현재 비활성이다.
중단 사유와 대체 구현은 바로 다음 주석 블록 참조. 이 블록은 판단 근거 보존용으로 남긴다.
─────────────────────────────────────────────────────────────────────────
개인정보보호 기능개선 사업 (SFR-004 / DBR-001 / SER-002) — 접속기록 한정 수집(#31)
· 위 COMTNSYSLOG용 syslog AOP(전 서비스 select* 대상)는 주석 그대로 유지(활성화하지 않음).
· 아래 personalDataLogAspect 는 '개인정보 처리 서비스'로 한정한 별도 체계다.
· personalDataLogAspect / jobMappingResolver / personalDataLogService 는
component-scan(context-common.xml, base-package egovframework/kr.or.arko)으로 등록되므로
여기서는 ref 로만 참조한다(대상 서비스 빈도 동일 root 컨텍스트).
· 스키마 기반 <aop:config> 라 aspectj-autoproxy 를 전역 활성화하지 않는다.
· 대상 확장 시: 이 pointcut 에 개인정보 처리 서비스 impl 만 추가(과수집 R2 방지). 게시판/공지 등 무관 조회 제외.
· #36(2026-07-21): 회원·업체 2개 지점 → 전 개인정보 처리 서비스(16종)로 확장. TRGET_ID 취득 규약은 PersonalDataLogAspect Javadoc 참조.
[제외] main/search/data/event/dept/orgnztchart/team/stat/provol/rspofc/prbro/prmvp/midact/srv/sample/test/excel 등 개인정보 미취급 서비스.
· 2026-08-06 과수집 1건 제외: BizTalentMberManageServiceImpl.selectJoinTalentMberList*
이 메서드는 취급자 업무가 아니라 프론트 공개 목록(메인 LayoutFrtController.main, frt 재능나눔 목록)이
공개동의분(PUBLIC_YN='Y')만 노출하는 경로다. 무인증 방문 1회당 ANONYMOUS 로그 1건이
730일 보관 테이블에 쌓여(실측 41건) 정기점검·이상탐지 통계를 희석시키므로 대상에서 뺀다.
같은 클래스의 취급자 경로(selectTalentMber/selectTalentMberList/selectTalentMberSingle)는 계속 수집한다.
========================================================================= -->
<!-- =========================================================================
[2026-08-07] 서비스 AOP 접속기록 수집 중단 — 관리자 화면 메뉴 접속기록으로 전환.
아래 <aop:config> 는 서비스 impl 메서드를 가로채 접속기록을 남겼다. 그러나 서비스는
관리자 화면과 프론트 화면이 함께 호출하므로 '어느 화면에서 불렀는지'를 구분할 수 없었고,
그 결과 무인증 프론트 방문이 접속자ID=ANONYMOUS, 수행업무="재능나눔 회원관리" 로 적재됐다
(공개 재능나눔 상세 /frt/biz/talent/bizTalentView.do → selectTalentMber).
selectJoinTalentMberList 를 pointcut 에서 빼는 식의 개별 예외로는 같은 문제가 계속 생긴다 —
프론트/관리자가 공유하는 서비스 메서드가 그것 하나가 아니기 때문이다.
대체 구현: egovframework.com.cmm.privacy.interceptor.MenuAccessLogInterceptor
(등록: WEB-INF/config/egovframework/springmvc/egov-com-servlet.xml)
요청 URL 로 관리자 화면만 골라내고, 기존 메뉴 테이블(COMTNMENUINFO)의 메뉴명을
수행업무로 남긴다. 적재 경로(AccessLogQueue → 해시체인 → PERSONAL_DATA_ACCESS_LOG)는 동일하다.
되돌리려면 아래 주석을 풀고 egov-com-servlet.xml 의 menuAccessLogInterceptor 등록을 제거할 것
(둘을 동시에 켜면 한 요청이 두 경로로 중복 적재된다).
========================================================================= -->
<!--
<aop:config>
<aop:aspect id="personalDataLogAspect" ref="personalDataLogAspect">
<aop:pointcut id="personalDataProcessPointcut"
expression="execution(* egovframework.com.uss.umt.service.impl.EgovMberManageServiceImpl.*(..))
or execution(* egovframework.com.uss.umt.service.impl.EgovEntrprsManageServiceImpl.*(..))
or execution(* kr.or.arko.frt.biz.ssn.service.impl.MberSsnServiceImpl.*(..))
or execution(* kr.or.arko.frt.biz.merge.service.impl.BizMberMergeServiceImpl.*(..))
or execution(* egovframework.com.uss.umt.service.impl.EgovUserManageServiceImpl.*(..))
or execution(* egovframework.com.uss.umt.service.impl.EgovDiapauseManageServiceImpl.*(..))
or execution(* egovframework.com.uss.umt.service.impl.EgovAccountUnlockManageServiceImpl.*(..))
or execution(* kr.or.arko.frt.biz.note.service.impl.BizNoteServiceImpl.*(..))
or execution(* kr.or.arko.frt.biz.sms.service.impl.BizSmsServiceImpl.*(..))
or (execution(* kr.or.arko.mnt.biz.talent.service.impl.BizTalentMberManageServiceImpl.*(..))
and not execution(* kr.or.arko.mnt.biz.talent.service.impl.BizTalentMberManageServiceImpl.selectJoinTalentMberList*(..)))
or execution(* kr.or.arko.mnt.biz.proapp.service.impl.BizProappServiceImpl.*(..))
or execution(* kr.or.arko.mnt.biz.appconfirm.service.impl.BizAppconfirmServiceImpl.*(..))
or execution(* kr.or.arko.mnt.biz.proresult.service.impl.BizProresultServiceImpl.*(..))
or execution(* kr.or.arko.mnt.biz.group.service.impl.BizGroupManageServiceImpl.*(..))
or execution(* kr.or.arko.mnt.biz.mileage.service.impl.BizMileageServiceImpl.*(..))
or execution(* kr.or.arko.mnt.biz.profile.service.impl.BizProfileServiceImpl.*(..))" />
<aop:around pointcut-ref="personalDataProcessPointcut" method="around" />
</aop:aspect>
</aop:config>
-->
</beans>