@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry())
;
}
}chrome 에서 admin 계정으로 로그인 후(SessionId를 부여 받음) 새탭에서 다시 admin 계정으로 로그인을 하면
동일한 SessionId 에서 로그인 시도를 했기 때문에
ConcurrentSessionControlAuthenticationStrategy.onAuthentication() 에서
123라인의 allowableSessionsExceeded() 메소드(중복로그인 exception)를 호출하지 않고 종료가 된다.
CompositeSessionAuthenticationStrategy.onAuthentication() 에서 fixation 기본값 인 migrateSession에 의해 AbstractSessionFixationProtectionStrategy 가 delegate 된다. (89라인)
AbstractSessionFixationProtectionStrategy.onAuthentication() 에서
Session Fixation Attack 방지로 인해 NewSessionId가 생성된다.
즉, 동일 로그인ID ‘admin’ 으로 SessionId, NewSessionId 각 2개가 생성되었다.
탬 1, 탭2 의 브라우저 cookie 에는 마지막으로 생성된 NewSessionId가 부여되며, 기존 SessionId를 해제를 하지 못한 상태로 Client 에서 사라지게 된다.
즉, NewSessionId로 로그아웃을 하더라도 ‘admin’ 계정에 대한 SessionId가 존재하므로 재 로그인 시 중복된 로그인 에러가 뜨게 된다.
// migrateSession : 새로운 세션을 생성하고 기존의 세션 값들을 새 세션에 복사해준다. 기본값으로 설정되어 있다.
// none : 아무것도 수행하지 않는다. 원래의 세션이 유지된다.
// newSession : "깨끗한" 새로운 세션을 생성한다. 기존의 세션데이터는 복사하지 않는다.
http.sessionManagement()
.sessionFixation().none()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry())