[Spring Security] Security 기본 API 이해 #6

권영태·2023년 7월 31일

Security

목록 보기
6/6

이 포스트는 정수원님의 스프링 시큐리티 강의 수강 후 정리한 글입니다.

인증 API

동시 세션 제어

  • 최대 세션 허용 개수를 초과했을 때 2가지의 정책이 있다. 하나는 "이전 사용자 세션 만료 정책" 또 다른 하나는 "현재 사용자 인증 실패 정책"이다.
  • 이전 사용자 세션 만료 정책은 뒤에 로그인한(세션 연결) 사용자의 세션 생성과 동시에 이전 사용자의 세션 만료를 설정해 이전 사용자의 세션을 만료시킨다.
  • 현재 사용자 인증 실패 정책은 뒤늦게 로그인을 시도한 사용자의 인증 예외를 발생시켜 세션 생성을 막는 정책이다.
  • 동시 세션 제어를 위한 코드는 다음과 같다.
http.sesssionManagement() // 세션 관련 기능 작동
	.maximumSession(1)  // 최대 세션 허용 개수 설정  * -1은 무제한 허용
    .maxSessionsPreventsLogin(true) // 동시 로그인 차단 * 2번 정책, false는 1번 정책
    .invalidSessionUrl("/invalid") // 세션이 유효하지 않을 때 이동할 URL
    .expiredUrl("/expired") // 세션이 만료될 경우 이동할 URL

세션 고정 보호

  • 공격자가 JSESSIONID를 변형시킨 후 사용자가 공격자 세션쿠키를 사용하게 한 후 사용자가 이를 이용해 로그인을 성공하면 공격자는 사용자 정보를 공유받을 수 있다.
  • 이러한 공격을 방어하기 위해 세션 고정을 보호해 변형시킨다.
    방법은 다음과 같다.
http.sessionManagement()
	.sessionFixation().changeSessionId() // default, 서블릿 3.1 이상 기본값으로 SessionId를 계속 변경하며, 이전의 세션에서 설정한 값들을 그대로 사용할 수 있다.
  //.sessionFixation().migrateSession()  // 서블릿 3.1 이하 기본값으로 SessionId를 계속 변경하며, 이전의 세션에서 설정한 값들을 그대로 사용할 수 있다.
  //.sessionFixation().newSession()  // SessionId를 계속 변경하며, 이전의 세션에서 설정한 값들은 계속 새로 설정해야된다. 
  //.sessionFixation().none()  // SessionId를 그대로 사용해 공격에 취약하다.

세션 정책

http.sessionManagement()
	.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)  // 스프링 시큐리티가 필요시 세션 생성
  //sessionCreationPolicy(SessionCreationPolicy.ALWAYS)  // 스프링 시큐리티가 항상 세션 생성
  //sessionCreationPolicy(SessionCreationPolicy.NEVER)  // 스프링 시큐리티가 세션을 생성하지 않지만 이미 존재한다면 사용
  //sessionCreationPolicy(SessionCreationPolicy.STATELESS)  // 스프링 시큐리티가 생성하지 않고 존재해도 사용하지 않음

ConcurrentSessionFilter

  • SessionManagementFilter와 동일하게 동시적 세션 제어를 수행한다.
  • 매 요청마다 현재 사용자의 세션 만료 여부를 체크하고 세션이 만료 되었다면 즉시 만료 처리한다.
    • 만료 여부 체크 :
      if(session.isExpired() == true)
    • 즉시 만료 처리 : Logout 처리, 즉시 오류 페이지 응답

SessionManagementFilter & ConcurrentSessionFilter 동작 원리

  • 가정 : maximumSession(1), 동시 세션 제어 전략 -> 이전 사용자 세션 만료 전략 채택
  • 새로운 사용자가 /login Request -> SessionManagementFilter에서 maximumSession()을 확인하고 최대 세션 허용 개수가(maximumSession(1)으로 가정) 초과되었을 경우 동시 세션 제어 전략인 이전 사용자 세션 만료 즉 session.expireNow()를 진행
  • 이후 이전 사용자가 새로운 Request -> ConcurrentSessionFillter가 session.isExpired() == true를 확인하는데 이전에 SessionManagementFilter가 진행한 session.expireNow()로 인해 세션 만료를 확인
  • 이로 인해 이전 사용자의 세션을 만료 시키고 Logout과 오류 페이지(This session has been expired)를 응답한다
profile
GitHub : https://github.com/dudxo

0개의 댓글