Spring

[spring] session 만료되었으나 제거되지 않는 문제

behonestar 2016. 5. 4. 17:54

기존 설정

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) {

        ...

    }

}



동작원리

  1. org.springframework.security.web.session.ConcurrentSessionFilter 시작되면 SessionRegistry로부터 session 정보를 얻어온다.
  2. SessionRegistry의 interface는 SessionRegistryImpl로 구현되어 있다.
  3. SessionRegistryImpl은 SessionDestroyedEvent 이벤트를 listen하고 있다.
  4. session이 만료될 때 이벤트가 발생하면 SessionRegistryImpl은 registry에서 해당 session을 제거한다.


'Spring' 카테고리의 다른 글

[Spring] DataSource 의존성 주입  (0) 2016.07.12