Spring Security는 기본적으로 JSESSION이라는 쿠키를 클라이언트에서 전송하여 세션에 따라 사용자 정보를 유지하는데, 세션 관리를 위해 Spring Security는 여러 기능을 제공한다
세션 관리
첫 번째로 세션이 만료되었을 때 사용자를 내가 지정한 URI로 redirect 할 수 있다
http.sessionManagement(sessionConfig -> sessionConfig.invalidSessionUrl("/invalidSession"))
세션이 만료되면 /invalidSession 이라는 URI로 redirect가 되고, /invalidSession 경로의 REST API가 있다면 세션 만료 시 서버에서 필요한 로직들을 수행할 수 있을 것이다.
두 번째로 사용자 별 세션을 몇개 최대 유지할 것인지, 해당 세션보다 추가적으로 세션이 생긴다면 이를 어떻게 처리할 것인지를 명시할 수 있다.
http.sessionManagement(sessionConfig -> sessionConfig.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.expireUrl("/expiredSession"))
.maximumSession()으로 세션의 최대 개수를 지정할 수 있고,
.maxSessionsPreventsLogin()를 통해 최대 세션를 초과하는 세션이 들어왔을 때 처리할 방식을 지정할 수 있다.
인자를 true를 주면 이전 세션을 없애고 들어온 세션을 생성한다.
.expiredUrl()는 세션 만료 시 redirct할 URI를 지정한다. 위에서 .invalidSessionUrl()와 같은 기능을 한다.
세 번째로 세션 타임아웃 시간을 정할 수 있다.
property 및 yml 파일에서 설정할 수 있고, 명시적으로 설정하지 않으면 기본값으로 30분이 설정된다.
참고로 세션 타임아웃은 2분 이상만 설정 가능하다.
sever.servlet.session.timeout=20m
Session Fixation Protection
Spring은 세션을 통해 사용자 정보를 불러오므로, 사용자들의 세션을 통한 공격이 여럿 존재한다.
간단하게 정리하면 session ID를 직접 탈취하여 사용자인 척 하는 방식인 세션 하이재킹,
공격자가 사용자에게 자신의 session ID를 제공하여 사용자가 해당 session ID를 가진 사이트로 이동하게끔 유도해 사용자인 척 하는 방식인 session fixiation이 존재한다.
Spring Security에서는 Session Fixation을 방지하기 위해 session을 관리하는 세 가지 전략을 제공하고, 해당 전략 중 어떤 전략을 택할 지 개발자가 명시할 수 있다.
각 전략에 대한 옵션은 changeSessionId, newSession, migrateSession 이 있다.
changeSessionId는 Spring Security의 default 전략으로, 새로운 session을 생성하지 않고, 단지 session ID만 바꾸는 전략이다.
newSession은 완전 새로운 session을 만드는 전략이다. 이 때 기존 세션에 들어있는 데이터들은 복사하지 않고, 기존 세션에서 spring security와 관련된 속성들만 복사한다.
migrateSession은 새로운 session을 만들고, 기존 세션의 모든 데이터를 복사하는 전략이다.
이러한 전략들 중 원하는 전략을 아래와 같이 security config에 등록할 수 있다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.sessionManagement((session) -> session
.sessionFixation((sessionFixiation) -> sessionFixiation.newSession()
)
);
return http.build();
}