springframework/시작하자SpringSecurity

9.세션 동시 제어 / 세션 고정 보호 / 세션 정책

Jungsoomin :) 2020. 9. 21. 02:16

동시세션 제어 전략이란.

최대 세션의 허용 개수가 초과되었을 때에 Session을 어떻게 유지시킬 것인지에 대한 전략이다.

 

  허용 세션 개수가 1개임을 가정.  2가지의 전략을 가진다.

 

 

이전 사용자 세션 만료 전략

  1. 사용자 1이 인증 요청 후 성공 SpringSecurity는 Session을 생성해준다.

  2. 사용자 2가 같은 계정으로 인증 요청 후 성공 SpringSecurity는 Session을 생성해주고 이전사용자의 Session은 Expire 설정을 걸어 둠

  3. 사용자 1이 다시 자원을 요청하면 SpringSecurity는 만료 설정된 사용자 1의 Session을 실제로 expired 시켜버림

즉, 새로운 인증 성공시 마다 이전 사용자의 세션은 만료 설정되고 이전 사용자가 자원접근을 요청할 경우 이전사용자의 Session은 expired 됨

 


현재 사용자 인증 실패 전략

  1. 사용자 1이 인증 요청 후 성공, SpringSecurity 는 Session을 생성해 줌.

  2. 사용자 2가 인증을 요청 후 성공, SpringSecurity 는 인증에 성공했더라도 인증예외를 발생시켜 로그인을 차단

즉, 첫번째 사용자의 Session 만이 남게 됨


동시 세션제어의 API들

  http.sessionManagement() : 세션관리 기능 작동

 

 sessionManagement() 의 하위 API

  1. maximumSessions(1) : 최대 허용 가능 세션의 수 , -1이라면 무제한

  2. maxSessionsPreventLogin(false) : 동시로그인 차단여부, true 라면 현재 사용자 인증 실패전략, false 라면 이전 사용자 세션 만료 전략, default = false

  3. invalidSessionUrl("/invalid") : 세션이 유효하지 않을시 이동 페이지

  4. expriedUrl("/expired") : 세션이 만료되었을 경우 이동 페이지

invalidSessionUrl() 과 expiredUrl() 이 같이 있을 경우 invalideSessionUrl() 이 우선순위 .

 

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()// 권한 요청들에
                .anyRequest()//어떤 요청이든
                .authenticated();// 인증을하겠다.

        http
                .formLogin();//폼로그인 방식으로 하겠다.


        http
                .sessionManagement()//세션 관리를 하겠다.
                .invalidSessionUrl("/login")//세션만료시 이동할 경로
                .maximumSessions(1)//최대 세션을 정하겠다.
                .maxSessionsPreventsLogin(true);//최대세션 관리전략을 정하겠다. true = 현제사용자 로그인 차단 false : 이전사용자 만료전략

    }
}

세션 고정 공격..?

  1. 공격자가 서버에 인증 요청 후 성공, 서버는 JSESSIONID를 발급 

  2. 공격자가 받은 JSESSIONID 쿠키를 사용자에게 심어놓음

  3. 사용자가 인증을 시도할때 JSESSIONID 는 공격자의 JSESSIONID 이므로 공격자의 JSESSIONID로 사용자가 인증에 성공

  4. 공격자와 사용자는 같은 JSESSIONID를 공유하기 때문에 공격자가 사용자의 정보를 공유하게 됨


세션 고정 공격을 방지하고자 SpringSecurity는 세션 고정 보호 기능을 제공한다.

 

인증에 성공 할 때 마다 새로운 세션을 만들어 JSESSIONID 를 새로 발급해주어 세션 고정 공격을 방지한다.


세션 고정 보호의 API들

http.sessionManagement() < 동시 세션 제어와 동일

 

세션 고정 보호의 하위 API

  1. sessionFixation().changeSessionId() : Servlet 3.1 이상대의 default

  2. sessionFixation().migrateSession() : Servlet 3.1 미만의 버전의 default

  3. sessionFixation().newSession() : JSESSIONID 와 세션을 새롭게 생성하는 부분은 동일, 이전 Session 속성은 가져오지 않음.

  4. sessionFixation().none() : 기존의 세션을 사용, 세션 고정 공격에 취약.

 

굳이 설정해주지 않더라도 SpringSecurity 초기화 시 자동으로 세션 고정보호를 설정해준다.

@Configuration
@EnableWebSecurity
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .authorizeRequests()
                .anyRequest().authenticated();

        http
                .formLogin();

        http
                .sessionManagement()//세션 관리
                .sessionFixation()//세션 고정 보호 전략을 세우겠다.
//                .none();//세선 고정 보호 전략을 세우지 않겠다.
//                .migrateSession()//Servlet 3.1 미만의 세션 고정 보호
                .changeSessionId();//Servlet 3.1 이상의 세션 고정 보호

    }
}

세션정책

http.sessionManagement() : 동시 세션 제어 와 세션 고정 보호와 동일

 

  세션 정책의 하위 API

  1. sessionCreationPolicy(SessionCreationPolicy.If_Required) : default = SessionCreationPolicy.if_Required

  • SessionCreationPolicy.Always : 항상 세션 생성

  • SessionCreationPolicy.If_Required : 필요시 세션 생성 

  • SessionCreationPolicy.Never : 세션을 생성하지 않지만 존재시에는 사용

  • SessionCreationPloicy.Stateless : 세션을 생성하지않으며 존재 시에도 쓰지않음, JWT(Json Web Token) 등을 쓸 때에 사용