Commit Graph

4 Commits

Author SHA1 Message Date
infraurp
94da0fe9ae 개인정보보호 기능개선 3차 — 접근통제 정책 화면 외 미커밋 산출물 일괄 커밋
5개 세션에 걸쳐 쌓인 미커밋 변경분을 한 번에 정리한다. 주 산출물은 이번 세션의
접근통제 정책 적용(SER-001 요건 4·5)이고, 나머지는 앞선 세션들의 백로그다.

■ 접근통제 정책 적용 (SER-001 요건 4·5, 이번 세션)
「개인정보보호강화 파일럿 개발항목」 접근통제 정책 적용(Action2) 시안 반영.

- ACCESS_CONTROL_POLICY(단일행) + 관리자 화면 신규 (메뉴 9100047)
  · 계정 잠금: 인증 실패 임계값(10 -> 5), 잠금 해제 방식(관리자화면+이력 / +사유필수)
  · 자동 로그아웃: 미사용 시간(60 -> 30분), 만료 임박 안내 사용여부·시점
  · 세션 재발급: 2차 인증 성공 시 세션 고정(Session Fixation) 차단 여부
- SessionPolicyInterceptor 신규 — /mnt/ 요청마다 정책값으로 세션 타임아웃 적용.
  web.xml 재배포 없이 값이 바뀐다(2025.9 자료요청 3번 "시간 설정 기능 없음" 해소).
  web.xml <session-timeout>30 은 이제 폴백값이다.
- 잠금 임계값 저장 시 인증 경로가 읽는 LOGIN_LOCK_COUNT 를 함께 동기화.
  정책 테이블만 고치면 화면 숫자만 바뀌고 실제 인증은 옛 값을 계속 쓰기 때문이다.
- 관리자 상단(top.jsp): 로그인 후 경과시간 + 자동 로그아웃 잔여 카운트다운,
  만료 임박 안내와 연장(/mnt/session/extend.do).
  세션 상태를 주기 폴링하지 않는다 — 그 요청 자체가 세션을 갱신해
  '미사용 자동 로그아웃'이 영원히 오지 않기 때문이다.
- 자동 로그아웃 시 로그인 화면 이동: actionLogout.do?expired=Y 로 세션 invalidate 후
  로그인 화면 + 사유 안내. 수동 로그아웃(프론트 메인 이동)은 기존 동작 유지.
- 계정잠금관리: 정책이 '사유 필수'면 해제 사유 강제, ACCOUNT_UNLOCK_HISTORY 적재.

■ EgovLoginLogAspect fail-safe (회귀 수정)
접속기록 적재 예외가 @Before 어드바이스 밖으로 나가 로그인·로그아웃이 통째로 500 이
되고 있었다(로컬: MySQL 8 + mysql-connector 5.1.17 의 tx_isolation 조회 실패).
클래스 Javadoc 이 이미 fail-safe 를 명세하고 있었으나 구현이 따르지 않았다.
try/catch 로 인증 흐름을 살리되, 접속기록 유실은 SFR-004 직결이라 ERROR 로 남긴다.

■ 앞선 세션 백로그
- 접속기록(SFR-004): 조회·CSV 비동기 다운로드(PDAL_DOWNLOAD_JOB), 업무유형 매핑
- 로그인 접속기록(#62): COMTNLOGINLOG 접속IP·접속ID 유실 복구 + 접속위치 스냅샷
- 권한관리(SFR-001): 권한변경 이력 CSV 비동기 다운로드, 신청·승인 워크플로 화면 정리
- 미사용계정(SFR-002): 현황 화면 시안 반영(요약·역할·잠금/말소·조치 이력)
- 회원정보 암호화(추가제안 Action4): AES 암복호화·검색용 해시, 이관 배치와 사전 백업

■ 커밋 제외
font/(글꼴 설치본 22M), 제안서 문서(pptx/hwp), .claude/(하네스) 는 소스가 아니라 제외.
.claude/ 버전관리 여부는 별도 판단이 필요하다.

배포 산출물: _workspace/deploy/20260810_1300/ (DELTA.md, sql/, APPLY_LOG.md)
브라우저 검증(2단계 인증 필요)은 APPLY_LOG.md B1~B7 로 남겨둔다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 13:58:58 +09:00
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
infraurp
65bbe591d1 인증 실패 이력 IP 기록·보관기간·조회화면 구현 (#22-1)
All checks were successful
deploy-dev / deploy (push) Successful in 42s
#22(실패이력 활성 경로 이설)로 적재는 살아났으나 LOGIN_HISTORY가
ID/CREATE_DATE/GUBUN 3컬럼뿐이라 (1) 접속 IP 미기록 (2) 로그인 성공 시
당일 이력 DELETE로 무차별 대입 흔적 소멸 문제가 있었다.

- DDL: LOGIN_HISTORY에 CONECT_IP(45)/RESET_YN + 인덱스 2종,
  ACCOUNT_MNG_POLICY.LOGIN_HIST_KEEP_DAY(기본 730일) 추가
- 적재: insertFailHistory 컬럼 명시 전환 + ClientIpResolver IP 세팅
  (종전 무컬럼 VALUES(3값)은 컬럼 추가 시 ERROR 1136 — DDL과 한 쌍)
- 보존: 성공 시 DELETE -> RESET_YN='Y' 소프트 리셋.
  selectFailCount가 RESET_YN='N'만 세므로 계정잠금 동작은 종전과 동일
- 화면: /mnt/sec/loginFailHistory/listView.do (계정·구분·IP·기간·리셋여부
  검색 + 페이징), 메뉴 9100039 + left.jsp 분기
- 정책화면: 계정 관리 정책에 보관기간 입력 항목·검증 추가
- 배치: purgeExpiredLoginFailHistoryScheduler 매일 03:30, 1회 5,000건 상한
- Mysql/Oracle sqlmap 쌍 + sql-map-config 등록

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 14:48:24 +09:00
infraurp
2a2ab99d10 개인정보보호 기능개선 사업 구현 (SFR-001~004, 권한관리·인증체계·접속기록)
권한관리(SFR-001):
- getAuthorities() 구현(EgovUserAuthorityDAO), AuthorityInterceptor 역할별 URL 접근제어
  (COMTNMENUCREATDTLS×COMTNMENUINFO×COMTNPROGRMLIST 메뉴권한 기반, 캐시/TTL, ROLE_ADMIN 바이패스)
- 권한 신청·승인 워크플로 + AUTHOR_CHANGE_HISTORY 이력(3년 보관), 조회·다운로드
계정관리(SFR-002): 계정관리정책, 장기미사용(휴면) 확장(취급자 포함)·사전알림, 계정잠금 5회
인증체계(SFR-003): 로그인 통합 2단계 인증(SecondFactorInterceptor+SecondFactorController),
  OTP QR 등록(ZXing)·비밀키 DB 영속(OTP_DEVICE, AES-GCM), 세션재발급(고정공격 방지), 자동로그아웃 30분
접속기록(SFR-004): PERSONAL_DATA_ACCESS_LOG(월파티션), PersonalDataLogAspect 한정수집,
  SHA-256 해시체인 무결성, 업무유형매핑, IP 취득보정, 비정상접근 탐지, 정기점검 리포트
DB: privacy DDL 11종 + 설치용 통합 SQL(privacy.install_mysql.sql, DDL+시드 DML)
빌드복구: pom.xml 시스템 jar/JAXB 선언, iBatis2 SQL주석 '#'→'No.' 정정

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 18:03:02 +09:00