기존 Spring Boot 애플리케이션에 Contexa 통합하기

이미 Spring Security가 적용된 Spring Boot 애플리케이션이 있습니다. Contexa를 추가해도 기존 보안 설정은 대체되지 않습니다 — 그 위에 감싸집니다. 이 페이지는 무엇이 바뀌고, 무엇이 그대로 유지되며, 어떻게 안전하게 도입하는지 설명합니다.

내부에서 일어나는 일

애플리케이션 클래스에 @EnableAISecurity를 추가하면, 4계층 파이프라인이 선언적 설정을 Spring Security 필터 체인으로 변환합니다.

1

Import & Detect

@EnableAISecurityAiSecurityImportSelector를 임포트하고, AiSecurityConfiguration을 로드합니다. 커스텀 PlatformConfig 빈이 없으면(@ConditionalOnMissingBean), 기본값이 자동 생성됩니다.

2

Create Flows

FlowContextFactoryPlatformConfig를 읽고 각 인증 흐름(Form, REST, MFA, OTT, Passkey)마다 독립적인 HttpSecurity 인스턴스를 생성합니다.

3

Apply Adapters

SecurityConfigurerOrchestrator가 어댑터 체인을 실행하여 Spring Security 메서드를 호출합니다: http.formLogin(), http.webAuthn()(DSL의 passkey()가 호출), http.oneTimeTokenLogin(). Zero Trust 필터도 이 단계에서 추가됩니다.

4

Register Chains

SecurityFilterChainRegistrar가 각 HttpSecurityOrderedSecurityFilterChain으로 감싸고 BeanDefinitionRegistry를 통해 Spring 빈으로 등록합니다 — 기존 필터 체인과 나란히, 절대 대체하지 않습니다.

기본 PlatformConfigForm Login + OTT MFA 흐름, 세션 관리, 그리고 AI 신뢰 점수를 위한 AISessionSecurityContextRepository를 제공합니다 — 설정 클래스를 하나도 작성하지 않아도 됩니다.

마법이 아닙니다. 내부적으로 Contexa는 여러분이 직접 호출하는 것과 동일한 Spring Security 메서드를 사용합니다. 선언적 DSL로 추상화하고 Zero Trust 필터를 추가한 것뿐입니다. 언제든 rawHttp()로 DSL을 우회할 수 있습니다.

기존 보안 설정은 그대로 유지됩니다

새로운 보안 프레임워크를 도입할 때 가장 흔한 우려: "기존 설정이 깨지지 않을까?"

Contexa 추가 전
기존 SecurityFilterChain
기존 UserDetailsService
기존 AuthenticationProvider
spring.security.* 속성
Contexa 추가 후
기존 SecurityFilterChain (변경 없음)
기존 UserDetailsService (변경 없음)
기존 AuthenticationProvider (변경 없음)
spring.security.* 속성 (변경 없음)
+ Contexa SecurityFilterChain (별도 추가)
+ Zero Trust 필터 (별도 추가)
+ AI 세션 컨텍스트 (별도 추가)

깨지지 않는 이유

기존 빈 Contexa 추가 후 메커니즘
SecurityFilterChain 변경 없음 — Contexa 체인이 별도로 추가됨 BeanDefinitionRegistry + OrderedSecurityFilterChain
UserDetailsService 변경 없음 — 기존 구현이 우선 @ConditionalOnMissingBean
AuthenticationProvider 변경 없음 — Contexa가 별도 Provider 추가 AuthenticationManager 체인 공존
CSRF / CORS 설정 변경 없음 — 필요시 global()로 재정의 가능 기존 설정 기본 유지
spring.security.* 변경 없음 — 네임스페이스 충돌 없음 Contexa는 contexa.*security.zerotrust.* 사용

Shadow Mode로 안전하게 시작

Shadow Mode는 전체 Zero Trust 파이프라인 — 행동 분석, 위험도 산출, AI 결정 — 을 실행하지만 결정을 절대 강제하지 않습니다.

Shadow Mode

여기서 시작하세요. 기존 동작에 위험 없음.

  • AI가 모든 요청을 분석
  • 결정은 로그에만 기록
  • 사용자 차단이나 MFA 요구 없음
  • 실제 트래픽으로 행동 기준선 구축
  • 요청 오버헤드 최소 — 분석이 기본적으로 비동기로 수행됨

Enforce Mode

기준선이 확립되면 전환.

  • AI가 모든 요청을 분석
  • 결정이 실시간으로 강제됨
  • ALLOW 정상 통과
  • CHALLENGE MFA 요구
  • BLOCK 접근 차단
YAML
security:
  zerotrust:
    mode: SHADOW   # AI가 모든 요청을 분석하되, 강제하지 않음

security.zerotrust.mode 속성은 SecurityZeroTrustProperties에 바인딩됩니다(값: SHADOW, ENFORCE; 기본값 ENFORCE). SecurityZeroTrustProperties.isEnforcementEnabled()mode == ENFORCE일 때만 true를 반환합니다. SHADOW 모드에서는 SecurityDecisionEnforcementHandler가 결정 영속화와 차단 부수 효과를 건너뛰고, AuthorizationManagerMethodInterceptor@Protectable(sync = true)의 BLOCK/CHALLENGE/ESCALATE 결정을 관찰 전용으로 처리합니다(ZeroTrustAccessDeniedException을 던지지 않고 메서드가 정상 진행). 이 속성은 @ConfigurationProperties로 바인딩되므로 YAML 값 변경 후에는 애플리케이션 재시작이 필요합니다.

프로덕션에서도 안전합니다. Shadow Mode는 어떤 요청이나 응답도 변경하지 않습니다. AI 분석은 요청 완료 후 비동기로 실행되어 지연 시간이 추가되지 않습니다. Shadow Mode 가이드 →

실전 적용 — Shadow에서 Enforce로

행동 기준선이 확립되면, 속성 하나를 변경하여 Enforce 모드로 전환합니다:

YAML
security:
  zerotrust:
    mode: ENFORCE   # AI 결정이 실제로 강제됨

Enforce 모드에서 AI의 결정이 실제로 적용됩니다:

ALLOW
요청이 정상 처리됨
!
CHALLENGE
MFA 재인증 요구
×
BLOCK
접근 즉시 차단
ESCALATE
관리자 검토 대기

롤백하려면 ENFORCESHADOW로 변경하세요. 해당 속성은 @ConfigurationProperties로 바인딩되므로 변경 사항이 적용되려면 애플리케이션 재시작이 필요합니다.

AI가 결정을 내리는 방식 →  |  마이그레이션 전략 →

커스텀 설정이 필요할 때

기본 PlatformConfig는 Form Login + OTT MFA + 세션 관리를 포함합니다. 다른 구성이 필요하면 직접 PlatformConfig 빈을 정의하세요:

시나리오 A: REST API 전용

애플리케이션이 REST API만 제공하고 Form Login이 필요 없는 경우.

Java
@Bean
public PlatformConfig platformConfig(IdentityDslRegistry<HttpSecurity> registry) throws Exception {
    return registry
        .global(globalHttpCustomizer)
        .rest(rest -> rest.order(10))
        .session(Customizer.withDefaults())
        .build();
}

시나리오 B: 기존 Form Login + Zero Trust

기존 인증 흐름을 유지하면서 AI 기반 보안만 추가하는 경우. 핵심: AISessionSecurityContextRepository 등록 필수.

Java
@Bean
public PlatformConfig platformConfig(IdentityDslRegistry<HttpSecurity> registry) throws Exception {
    return registry
        .global(http -> http
            .authorizeHttpRequests(authReq -> authReq
                .requestMatchers("/css/**", "/js/**", "/images/**").permitAll()
                .anyRequest().access(customDynamicAuthorizationManager))
            .securityContext(sc -> sc
                .securityContextRepository(aiSessionSecurityContextRepository)))
        .form(form -> form.defaultSuccessUrl("/dashboard"))
        .session(Customizer.withDefaults())
        .build();
}

시나리오 C: 복잡한 기존 설정 — rawHttp() 탈출구

DSL이 충분하지 않을 때 — 커스텀 필터, 커스텀 AuthenticationEntryPoint, 고급 설정 — Spring Security의 HttpSecurity에 직접 접근합니다:

Java
.form(form -> form
    .rawFormLogin(formLogin -> formLogin
        .authenticationDetailsSource(customDetailsSource)
        .successHandler(customSuccessHandler))
)

Spring Security의 FormLoginConfigurer에 완전히 접근하면서도 Contexa의 Zero Trust 파이프라인은 그대로 유지됩니다.

Zero Trust 필수 조건. 커스텀 PlatformConfig를 정의할 때 AISessionSecurityContextRepositoryglobal() 커스터마이저에 반드시 등록하세요. 빠뜨리면 세션에 AI 신뢰 점수가 주입되지 않아 Zero Trust가 작동하지 않습니다.

Identity DSL 레퍼런스 →  |  인증 흐름 →  |  적응형 MFA →