기존 Spring Boot 애플리케이션에 Contexa 통합하기
이미 Spring Security가 적용된 Spring Boot 애플리케이션이 있습니다. Contexa를 추가해도 기존 보안 설정은 대체되지 않습니다 — 그 위에 감싸집니다. 이 페이지는 무엇이 바뀌고, 무엇이 그대로 유지되며, 어떻게 안전하게 도입하는지 설명합니다.
내부에서 일어나는 일
애플리케이션 클래스에 @EnableAISecurity를 추가하면, 4계층 파이프라인이 선언적 설정을 Spring Security 필터 체인으로 변환합니다.
Import & Detect
@EnableAISecurity가 AiSecurityImportSelector를 임포트하고, AiSecurityConfiguration을 로드합니다. 커스텀 PlatformConfig 빈이 없으면(@ConditionalOnMissingBean), 기본값이 자동 생성됩니다.
Create Flows
FlowContextFactory가 PlatformConfig를 읽고 각 인증 흐름(Form, REST, MFA, OTT, Passkey)마다 독립적인 HttpSecurity 인스턴스를 생성합니다.
Apply Adapters
SecurityConfigurerOrchestrator가 어댑터 체인을 실행하여 Spring Security 메서드를 호출합니다: http.formLogin(), http.webAuthn()(DSL의 passkey()가 호출), http.oneTimeTokenLogin(). Zero Trust 필터도 이 단계에서 추가됩니다.
Register Chains
SecurityFilterChainRegistrar가 각 HttpSecurity를 OrderedSecurityFilterChain으로 감싸고 BeanDefinitionRegistry를 통해 Spring 빈으로 등록합니다 — 기존 필터 체인과 나란히, 절대 대체하지 않습니다.
기본 PlatformConfig는 Form Login + OTT MFA 흐름, 세션 관리, 그리고 AI 신뢰 점수를 위한 AISessionSecurityContextRepository를 제공합니다 — 설정 클래스를 하나도 작성하지 않아도 됩니다.
마법이 아닙니다. 내부적으로 Contexa는 여러분이 직접 호출하는 것과 동일한 Spring Security 메서드를 사용합니다. 선언적 DSL로 추상화하고 Zero Trust 필터를 추가한 것뿐입니다. 언제든 rawHttp()로 DSL을 우회할 수 있습니다.
기존 보안 설정은 그대로 유지됩니다
새로운 보안 프레임워크를 도입할 때 가장 흔한 우려: "기존 설정이 깨지지 않을까?"
깨지지 않는 이유
| 기존 빈 | 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 접근 차단
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 모드로 전환합니다:
security:
zerotrust:
mode: ENFORCE # AI 결정이 실제로 강제됨
Enforce 모드에서 AI의 결정이 실제로 적용됩니다:
롤백하려면 ENFORCE를 SHADOW로 변경하세요. 해당 속성은 @ConfigurationProperties로 바인딩되므로 변경 사항이 적용되려면 애플리케이션 재시작이 필요합니다.
커스텀 설정이 필요할 때
기본 PlatformConfig는 Form Login + OTT MFA + 세션 관리를 포함합니다. 다른 구성이 필요하면 직접 PlatformConfig 빈을 정의하세요:
시나리오 A: REST API 전용
애플리케이션이 REST API만 제공하고 Form Login이 필요 없는 경우.
@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 등록 필수.
@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에 직접 접근합니다:
.form(form -> form
.rawFormLogin(formLogin -> formLogin
.authenticationDetailsSource(customDetailsSource)
.successHandler(customSuccessHandler))
)
Spring Security의 FormLoginConfigurer에 완전히 접근하면서도 Contexa의 Zero Trust 파이프라인은 그대로 유지됩니다.
Zero Trust 필수 조건. 커스텀 PlatformConfig를 정의할 때 AISessionSecurityContextRepository를 global() 커스터마이저에 반드시 등록하세요. 빠뜨리면 세션에 AI 신뢰 점수가 주입되지 않아 Zero Trust가 작동하지 않습니다.