ApplicationListener<SessionDestroyedEvent> 란?
Spring Security 에서 세션(Session) 이 종료되거나 만료될 때 발생하는 이벤트를 감지하는 리스너이다.
보통 아래 상황에서 실행된다.
- 세션 타임아웃 만료
- 로그아웃
- 세션 강제 제거
- Cocurrent Session Control 로 인한 세션 종료
SessionDestroyedEvent
SessionDestroyedEvent 는 단순히 브라우저 탭을 닫는 순간이 아니라, Spring Security 가 관리하는 세션이
만료되거나 무효화될 때 발생하는 이벤트입니다. 이 이벤트 안에는 보통 해당 세션에 연결된 SecurityContext 목록이
들어있어서, 어떤 사용자의 세션이 끝났는지 확인할 수 있습니다.
보통 같이 필요한 것(HttpSessionEventPublisher)
해당 리스너만 등록해서는 부족하고, HttpSessionEventPublisher 도 함께 등록해야 세션 생성/삭제 이벤트가
Spring Security 이벤트로 전달됩니다. Spring Boot 에서는 보통 설정 클래스에
ServletListenerRegistrationBean<HttpSessionEventPublisher> 형태로 빈 등록을 합니다.
@Bean
HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
@Bean
ServletListenerRegistrationBean<HttpSessionEventPublisher> getHttpSessionEventPublisher() {
return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(httpSessionEventPublisher());
}
왜 필요하냐?
Spring Security 는 기본적으로 WAS 의 세션 이벤트를 직접 받지 못한다.
아래 구조처럼 WAS 의 이벤트를 HttpSessionEventPublisher 리스너가 대신 받아 Spring Event 로 변환하여
SessionDestroyedEvent 를 발생시킨다.
WAS Session Event
↓
HttpSessionEventPublisher
↓
Spring Event 로 변환
↓
SessionDestroyedEvent 발생
간단 예시
SessionDestroyedEvent 는 Spring Security 가 발행하는 이벤트이다.
@Component
public class SessionDestroyedListener
implements ApplicationListener<SessionDestroyedEvent> {
@Override
public void onApplicationEvent(SessionDestroyedEvent event) {
System.out.println("세션 종료됨");
event.getSecurityContexts().forEach(context -> {
String username = context.getAuthentication().getName();
System.out.println("로그아웃 사용자 : " + username);
});
}
}