[Spring Security] 세션(Session) 관리

SeongWon Oh·2022년 1월 3일
0

Spring Framework

목록 보기
31/33
post-thumbnail
post-custom-banner

생성된 계정으로 서버로부터 인증을 받게 되면 서버에 하나의 세션이 생성됩니다. 그리고 다른 브라우저, 또는 다른 PC에서 같은 계정으로 로그인을 할 경우 이전에 서버에 만들어진 세션을 같이 공유하는 것이 아닌 새로운 세션을 생성하여 사용하게 됩니다.
이번 Post에서는 이러한 세션의 개수 제한 등의 여러 설정에 대하여 알아보고자 합니다.

1. 동시 세션 관리

스프링 시큐리티에서는 한개의 계정에 대해 생성되는 세션의 개수를 설정하고 세션이 최대 개수가 되었을 때 처리할 방법을 쉽게 설정할 수 있습니다. 해당 설정은 1.1에서 설명할 maximumSessions(), maxSessionsPreventsLogin()를 통해 할 수 있다.

1.1 동시 세션 관리 설정 코드

    protected void configure(HttpSecurity http) throws Exception {     
        http.sessionManagement()
                .maximumSessions(1)
                .maxSessionsPreventsLogin(true)
                .invalidSessionUrl("/invalid")
                .expiredUrl("/expired ");
    }
  • maximumSessions(1) : 최대 허용 가능 세션 수를 설정하는 api이다. (값으로 -1을 넣으면 무제한으로 세션 생성을 허용하게 된다.)
  • maxSessionsPreventsLogin(true) : 위에서 설정한 최대 허용 세션의 수가 되었을 때 추가적인 인증 요청(세션 생성)이 있을 경우 어떻게 처리를 할지 정하는 api이다.(true면 현재 사용자 인증 실패, false(default값)면 기존 세션 만료하게 딘다.)
  • invalidSessionUrl("/invalid") : 세션이 유효하지 않을 때 이동 할 페이지를 설정하는 api이다.
  • expiredUrl("/expired ") : 세션이 만료된 경우 이동 할 페이지를 정하는 api이다.

1.1. 최대 세션의 개수일 때 처리 방법

maximumSessions()의 설정이 1이라 하였을 때를 기준으로 설명하겠습니다.
1. 이전의 사용자 세션 만료
step 1. 사용자 1이 로그인을 하면 서버에 해당 계정에 대한 세션이 생성됩니다.
step 2. 사용자 2가 사용자 1이 로그인 하였던 동일 계정으로 로그인을 시도하게되면 여러 filter중 SessionManageMentFilter에서 maximumSessions()의 값이 1인 것을 확인합니다.
step 3. 서버는 새롭게 접근을 시도한 사용자 2의 세션을 새로 생성하고 인증을 해주며 사용자 1의 세션은 session.isExpired() == true으로 변경하여 세션 만료 설정을 해줍니다.
step 4. 사용자 1이 다시 request를 요청하면 ConcurrentSessionFilter에서 session.isExpired()값을 확인하여 세선이 만료여부를 확인 후 세션의 만료 여부를 확인 후 새로운 세션을 만들도록 인증을 요청하게 됩니다

2. 새로운 사용자 인증 실패
step 1. 사용자 1이 로그인을 하면 서버에 해당 계정에 대한 세션이 생성됩니다.
step 2. 사용자 2가 사용자 1이 로그인 하였던 동일 계정으로 로그인을 시도하게되면 여러 filter중 SessionManageMentFilter에서 maximumSessions()의 값이 1인 것을 확인합니다.
Step 3. 서버에서는 사용자 2의 세션을 생성되지 않고 인증 예외를 발생시킵니다.

  • ConcurrentSessionFilter : 매 요청마다 사용자 세션의session.isExpired() 여부를 확인하여 세션이 만료로 되어있을 경우 로그아웃처리(만료처리)를 해주는 필터입니다.
  • SessionManageMentFilter : 동시적 세션제어, 세션 고정 보호, 세션 생성 정책 등의 세션의 전반적인 관리를 해주는 필터입니다.
  • 두 필터의 세션 만료에 대한 전반 적인 동작은 다음과 같습니다.

2. 세션 고정 보호

고정된 세션 아이디를 가진 세션들을 사용하다보면 아래와 같이 공격자가 하나의 세션을 서버에 생성하고 해당 세션 아이디를 사용자에게 넘겨준다면 사용자와 공격자는 동일한 세션을 사용하게 되어서 공격자가 사용자의 정보들을 빼낼 수 있는 문제가 발생할 것입니다.

Spring Security는 이러한 문제를 기본적으로 보호해줍니다.

2.1. 세선 고정 보호 설정 코드

    protected void configure (HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionFixation().changeSessionId()
    }

해당 설정은 다음과 같이 4가지 옵션이 있습니다.

  • changeSessionId() : 사용자가 인증을 시도하게 되면 사용자 세션은 그대로 두고 세션 아이디만 변경을 합니다. -> 세션 아이디가 변경되어서 공격자가 갖고있는 세션 아이디는 무용지물이 됩니다. (서블릿 3.1 이후에서 기본값입니다.)
  • : 새로운 세션을 생성하고 세션 아이디도 새로 발급하며 migration합니다. (서블릿 3.1 이전에서 기본값입니다.)
  • newSession()- : 새로운 새션과 아이디 생성하며 이전의 설정 값들을 사용 불가합니다.
  • none() : 아무런 보호 X

changeSessionId(), migrateSession()은 이전 세션의 설정 값들을 그대로 사용할 수 있습니다. 하지만 newSession()의 경우 새로운 세션을 생성하여 이전 설정 값을 사용하지 못합니다.

해당 기능은 따로 설정을 하지 않아도 Spring Security가 기본적으로 적용합니다.

3. 세션 정책 설정

Spring에서는 세션 생성 및 사용 여부에 대한 정책을 설정할 수 있습니다.

3.1. 세션 정책 설정 코드

    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.If_Required)
    }

해당 설정은 다음과 같이 4가지 옵션이 있습니다.

  • SessionCreationPolicy.Always : 스프링 시큐리티가 항상 세션 생성g합니다.
  • SessionCreationPolicy.If_Required : 스프링 시큐리티가 필요 시 생성합니다.(default)
  • SessionCreationPolicy.Never : 스프링 시큐리티가 생성하지 않지만 이미 존재하면 사용합니다.
  • SessionCreationPolicy.Stateless : 스프링 시큐리티가 생성하지 않고 존재해도 사용하지 않습니다. (JWT와 같이 세션을 사용하지 않는 경우 사용)

Reference

profile
블로그 이전했습니다. -> https://seongwon.dev/
post-custom-banner

0개의 댓글