contexa-identity

Zero Trust 필터

인증 이후 요청 시점에서 접근 제어와 챌린지 연속 처리를 수행하는 서블릿 필터 체인입니다. 이 필터들은 AISessionSecurityContextRepository, MFA 컨텍스트 상태, ZeroTrustActionRepository와 함께 동작하여 Identity 계층 안에서 런타임 Zero Trust 결정을 집행합니다.

개요

Identity 계층은 두 개의 전용 서블릿 필터를 사용합니다. ZeroTrustAccessControlFilterBLOCK, ESCALATE, PENDING_ANALYSIS를 처리합니다. ZeroTrustChallengeFilterCHALLENGE 경로를 처리하고 MFA 챌린지 세션을 초기화하거나 재개합니다.


  Runtime Decision Path
  =====================

  [AISessionSecurityContextRepository]
              |
              v
  [인증된 요청]
              |
              +--> [ZeroTrustAccessControlFilter]
              |         |- BLOCK
              |         |- ESCALATE
              |         `- PENDING_ANALYSIS
              |
              `--> [ZeroTrustChallengeFilter]
                        `- CHALLENGE

ZeroTrustAccessControlFilter

io.contexa.contexaidentity.security.zerotrust.ZeroTrustAccessControlFilterZeroTrustActionRepository.getCurrentAction(userId, contextBindingHash)로 현재 액션을 읽습니다. 현재 런타임 결정이 BLOCK, ESCALATE, PENDING_ANALYSIS일 때만 요청을 가로챕니다.

결정동작
BLOCK요청을 즉시 차단하거나, block-MFA가 pending 상태이면 ChallengeMfaInitializer를 통해 block 해제용 MFA를 시작합니다.
ESCALATE에스컬레이션 응답을 반환하고 응답 writer를 통해 retry 메타데이터를 설정합니다.
PENDING_ANALYSIS확정적인 런타임 액션이 나올 때까지 pending-analysis 응답을 반환합니다.

이 필터는 shouldNotFilter(...)에서 logout, zero-trust API, /.well-known/ 경로를 건너뜁니다. 또한 MfaFlowUrlRegistry / AuthUrlProvider가 제공하는 MFA 페이지와 동적 MFA URL도 다시 차단하지 않도록 제외합니다.

ZeroTrustChallengeFilter

io.contexa.contexaidentity.security.zerotrust.ZeroTrustChallengeFilterCHALLENGE 액션을 처리합니다. 기존 MFA 챌린지 세션이 있으면 재사용하고, 없으면 ChallengeMfaInitializer.initializeChallengeFlow(...)를 호출해 새 챌린지 세션을 만듭니다.

브라우저 요청에는 /zero-trust/challenge-required?mfaUrl=...로 리다이렉트합니다. API 또는 AJAX 요청에는 mfaUrl, challengeNoticeUrl, sessionId, 현재 MFA state를 담은 JSON 오류 응답을 반환합니다.

shouldNotFilter(...) 제외 경로이유
/mfa/**, 동적 MFA 페이지 URL이미 MFA 플로우 안에 들어온 요청에서 챌린지 필터가 다시 트리거되는 것을 막습니다.
/api/mfa/**, /admin/api/mfa/**MFA 제어면 API를 보존합니다.
/webauthn/**, /login/webauthnWebAuthn 등록과 챌린지 처리가 정상적으로 진행되도록 합니다.
/zero-trust/**, /.well-known/**챌린지 안내 화면과 well-known 엔드포인트에서 루프가 생기지 않게 합니다.

저장소와 런타임 컨텍스트

두 필터는 독립적인 서블릿 필터가 아니라, 런타임 결정 저장소와 MFA 컨텍스트 서비스에 의존합니다.

구성요소역할
ZeroTrustActionRepository사용자와 컨텍스트 바인딩 해시에 대한 현재 런타임 액션을 저장/조회합니다.
AISessionSecurityContextRepository인증된 보안 컨텍스트를 로드하여 인증 이후 Zero Trust 결정 경로에 공급합니다.
MfaSessionRepositoryMFA 챌린지 세션을 저장하거나 재개합니다.
MfaFlowUrlRegistry / AuthUrlProvider브라우저 리다이렉트와 API 응답에 필요한 기본/접두사 적용 MFA URL을 제공합니다.
ChallengeMfaInitializer런타임 정책이 추가 검증을 요구할 때 challenge MFA를 부트스트랩합니다.

요청 시점 시퀀스


  Request-Time Zero Trust Sequence
  ================================

  [인증된 요청]
          |
          v
  [ZeroTrustActionRepository.getCurrentAction(...)]
          |
          +--> BLOCK / ESCALATE / PENDING_ANALYSIS --> [ZeroTrustAccessControlFilter]
          |
          `--> CHALLENGE --> [ZeroTrustChallengeFilter]
                                   |
                                   +--> 기존 MFA 세션 재사용 -> redirect / JSON 응답
                                   `--> initializeChallengeFlow(...) -> redirect / JSON 응답