- 세션의 생성, 소멸, 만료 이벤트의 동작 원리
- 세션 이벤트를 감지하기 위해 리스너를 등록하는 방법
- HttpSessionListener 와 Spring의 ApplicationListener 의 차이점
- 직접 세션 이벤트를 로그로 확인해보기
- 실무에서 세션 이벤트와 리스너를 어떻게 활용하는가
세션 이벤트와 리스너 개요
1. 개념
세션 이벤트(Session Event) 는 세션의 생성, 소멸, 만료 시점에 발생하는 이벤트임
리스너(Listener) 는 이러한 이벤트를 감지하고 특정 동작(로그 남기기, 리소스 정리 등) 을 수행할 수 있도록 돕는 컴포넌트임
HttpSessionListener 활용
1. HttpSessionListener 개념
- Java EE 표준 인터페이스
- sessionCreated, SessionDestroyed 메서드를 통해 세션의 생성 / 소멸을 감지한다
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CustomHttpSessionListener implements HttpSessionListener {
private static final Logger log = LoggerFactory.getLogger(CustomHttpSessionListener.class);
// 세션의 생성
@Override
public void sessionCreated(HttpSessionEvent se) {
log.info("[세션 생성] sessionId = {} 생성됨", se.getSession().getId());
}
// 세션의 소멸
@Override
public void sessionDestroyed(HttpSessionEvent se) {
log.info("[세션 소멸] sessionId = {} 소멸됨", se.getSession().getId());
}
}
등록하는 방법 (web.xml 또는 Spring Boot)
import com.b1uffer.cookieandsession.Listener.CustomHttpSessionListener;
import jakarta.servlet.http.HttpSessionListener;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ListenerConfig {
@Bean
public ServletListenerRegistrationBean<HttpSessionListener> httpSessionListener() {
return new ServletListenerRegistrationBean<>(new CustomHttpSessionListener());
}
}
Spring ApplicationListener 활용하기
1. Spring 이벤트 시스템 연계
- Spring 은 세션 관련 이벤트를 ApplicationEvent 로도 발행한다
- ApplicationListener 를 구현하거나, @EventListener 를 통해 간단하게 감지할 수 있다고 함
- HttpSessionCreatedEvent, HttpSessionDestroyedEvent 클래스를 통해 감지할 수 있다
2. 예제
SessionDestroyedEventListener.java
import org.springframework.context.ApplicationListener;
import org.springframework.security.web.session.HttpSessionDestroyedEvent;
import org.springframework.stereotype.Component;
/**
* SecuritySessionEventListener 랑 둘중에 선택해서 사용하면 됨
*/
@Component
public class SessionDestroyedEventListener implements ApplicationListener<HttpSessionDestroyedEvent> {
@Override
public void onApplicationEvent(HttpSessionDestroyedEvent event) {
event.getSecurityContexts().forEach(content -> {
String username = content.getAuthentication().getName();
System.out.println("[세션 만료 감지] 사용자 : " + username);
});
}
}
얘는 SessionDestroyedEvent의 구현체인 HttpSession 전용 이벤트를 받고 있다
SecuritySessionEventListener.java
import org.springframework.context.event.EventListener;
import org.springframework.security.core.session.SessionDestroyedEvent;
import org.springframework.stereotype.Component;
/**
* SessionDestroyedEventListener 랑 둘중에 선택해서 사용하면 됨
*/
@Component
public class SecuritySessionEventListener {
@EventListener
public void handleSessionDestroyed(SessionDestroyedEvent event) {
event.getSecurityContexts().forEach(context -> {
System.out.println("[세션 만료] 사용자 : " + context.getAuthentication().getName());
});
}
}
얘는 Spring Security의 상위 추상 이벤트인 SessionDestroyedEvent 를 받는다
SessionDestroyedEvent 가 HttpSessionDestroyedEvent 의 부모이다.
둘 다 세션 종료를 감지할 수 있음
둘 중 하나를 선택해서 사용하면 된다
실무적으로는 Spring MVC / Security 세션 만료에 대해 감지한다면 SessionDestroyedEvent 를 사용한다곤 하는데
구체적으로 보고 싶다면 HttpSessionDestroyedEvent 를 써도 될 것 같다
둘 다 Component로 등록하면 둘 다 반응해서 로그가 두 번 뜰 수 있다
SecurityContext 까지 함께 확인할 수 있어서 사용자 단위 세션 추적에 적합하다고 함
세션 만료 감지
1. 타임아웃 기반 만료
application.yml 에서 세션 타임아웃을 설정할 수 있다
server:
servlet:
session:
timeout: 30m
2. ConcurrentSessionFilter 기반 만료
- ConcurrentSessionFilter 는 동시 세션 제어와 함께 사용되며, 만료된 세션을 감지하고 처리한다
- 세션이 만료되면 HttpDestroyedEvent 가 발생하며, 리스너에서 이를 받아 처리할 수 있다
(1) 예제
import org.springframework.context.event.EventListener;
import org.springframework.security.web.session.HttpSessionDestroyedEvent;
import org.springframework.stereotype.Component;
@Component
public class ConcurrentSessionListener {
@EventListener
public void onSessionDestroyed(HttpSessionDestroyedEvent event) {
String sessionId = event.getSession().getId();
System.out.println("[ConcurrentSessionFilter] 세션 만료 감지 - ID : " + sessionId);
event.getSecurityContexts().forEach(context -> {
System.out.println("만료된 사용자 : " + context.getAuthentication().getName());
});
}
}
위 코드에서는 ConcurrentSessionFilter 가 만료된 세션을 감지하여 HttpSessionDestroyedEvent 를 발생시키고,
리스너에서 이를 로그로 기록한다
팁
- 로그 감사(Audit) : 보안상 중요한 서비스에서는 세션 생성 / 소멸을 모두 감사 로그에 기록한다
- 리소스 정리 : 세션 만료시 DB 커넥션, 캐시 자원 등을 해제하는 작업에 활용할 수 있다
- 보안 알림 : 특정 사용자 세션이 강제로 만료될 경우 알림을 발송하는 기능과 연계할 수 있다
정리
| 주제 | 핵심 포인트 |
| HttpSessionListener | 세션 생성 / 소멸 이벤트 감지 (Java EE 표준 서블릿) |
| ApplicationListener | Spring 이벤트로 세션 종료 감지, 사용자 정보와 함께 확인 가능함 |
| 세션 만료 | 타임아웃 또는 동시 세션 제어에 의해 발생함 |
| 활용 사례 | 감사 로그, 리소스 정리, 보안 알림 |
'Spring Boot > Security 쿠키,세션 기반 인증,인가' 카테고리의 다른 글
| 세션 관리 설정과 커스터마이징 : 세션 만료 후 처리 전략 (0) | 2026.05.08 |
|---|---|
| 세션 관리 설정과 커스터마이징 : 세션 타임아웃 설정 (0) | 2026.05.08 |
| 세션 관리 설정, 커스터마이징 : 세션 생성 정책 설정 (0) | 2026.05.07 |
| 세션 관리 핵심 컴포넌트 : 세션 관리 필터 (0) | 2026.05.06 |
| 세션 관리 핵심 컴포넌트 : SecurityContextHolder 와 SecurityContext (0) | 2026.05.06 |