기존 설정
security-context.xml
// 계정당 동시 로그인 제한 : 100개
<beans:property name="maximumSessions" value="100" />
tomcat web.xml
// 세션 만료 시간 : 30분
<session-timeout>30</session-timeout>
증상
session timeout 만료 후에도 session이 제거되지 않아 새로운 session 생성 불가능 (로그인 불가능)
단, 아래와 같이 명시적으로 expire시킨 경우에는 session이 제거된다.
expireDuplicatedLoginUser(...)
{
...
List<SessionInformation> list = sessionRegistry.getAllSessions( dupLoginUserName, false );
for ( int n = 0; n < list.size(); n++ ) {
SessionInformation info = list.get( n );
info.expireNow();
}
...
}
원인
SessionDestroyedEvent 이벤트를 발생시켜주는 Event Publisher가 등록되어 있지 않아 ConcurrentSessionFilter 필터가 세션 만료를 감지할 수 없음.
대책
SessionDestroyedEvent 이벤트를 발생시켜주는 Event Publisher를 등록함.
<!-- Session Create/Destroy Event Publisher -->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
결과
session이 만료될 때마다 sessionDestroyed가 호출되는 것을 확인
public class HttpSessionEventPublisher implements HttpSessionListener {
...
public void sessionCreated(HttpSessionEvent event) {
...
}
public void sessionDestroyed(HttpSessionEvent event) {
...
}
}
동작원리
- org.springframework.security.web.session.ConcurrentSessionFilter 시작되면 SessionRegistry로부터 session 정보를 얻어온다.
- SessionRegistry의 interface는 SessionRegistryImpl로 구현되어 있다.
- SessionRegistryImpl은 SessionDestroyedEvent 이벤트를 listen하고 있다.
- session이 만료될 때 이벤트가 발생하면 SessionRegistryImpl은 registry에서 해당 session을 제거한다.
'Spring' 카테고리의 다른 글
[Spring] DataSource 의존성 주입 (0) | 2016.07.12 |
---|