인증 상태 영속성

enxnong·2024년 6월 14일
0

스프링 시큐리티

목록 보기
3/13

정수원님의 강의 스프링 시큐리티 완전 정복 [6.x 개정판] 보면서 공부한 내용입니다.

SecurityContextRepository / SecurityContextHolderFilter

SecurityContextRepository

  • 스프링 시큐리티에서 사용자가 인증을 한 후 사용자의 인증을 유지하기 위해 사용하는 클래스
  • 사용자가 인증을 하게 되면 사용자의 인증 정보와 권한이 SecurityContext 에 저장되고 HttpSession을 통해 요청 간 영속이 이루어지는 방식

⭐ 인증 요청

  1. 사용자가 인증 요청하면 AuthenticationFilter가 인증 요청을 받아 사용자의 인증을 처리한다
  2. 사용자의 인증이 성공하면 인증정보를 SecurityContext에 저장한다
  3. SecurityContext에는 Authentication 인증 객체(user, authorty 등)가 저장된다
  4. 인증 상태를 유지하기 위해 SecurityContext를 명시적으로 저장소에 보관한다 (2가지 방법을 제공한다 ex: 세션에 저장하는 방식)
  5. SecurityContext를 저장하는 구현체인 SecurityContextRepository에 정보를 보관한다
  6. HttpSession에 SecurityContext를 저장하면 이후에는 요청할 때마다 세션으로부터 참조하여 요청 간의 연속이 이루어진다

⭐ 인증 후 요청

  1. SecurityContextFilter가 사용자가 이전에 SecurityContext를 제작했는지 아닌지 확인한다
  2. SecurityContextRepository로부터 SecurityContext를 로드한다
  3. HttpSession으로부터 컨텍스트 존재를 확인한 뒤 컨텍스트를 가져온다
  4. SecurityContext안의 Authentication이 null이 아닌 경우 사용자가 인증을 한 상태라는 것을 확인할 수 있다

💡 Authentication 타입이 Anonymous 인 경우는 제외한다

인터페이스 구현체

  • DelegatingSecurityContextRepository : RequestAttributeSecurityContextRepository 와 HttpSessionSecurityContextRepository 를 동
    시에 사용할 수 있도록 위임된 클래스로서 초기화 시 기본으로 설정된다

  • HttpSessionSecurityContextRepository : HttpSession에 보안 컨텍스트를 저장한다. 사용자의 세션이 살아있는 동안 인증 요청이 끝난 후에 또 다시 요청을 할 경우에도 컨텍스트 영속성을 유지한다

    💡 세션이 끝나는 순간 : timeout / 어플리케이션 종료

  • RequestAttributeSecurityContextRepository : ServletRequest 에 보안 컨텍스트를 저장한다. 세션에 저장한 것이 아니므로 컨텍스트 영속성이 유지되지 않는다.

    💡 ServletRequest는 매 요청마다 요청객체가 바뀌므로 영속성을 유지할 수 없다

  • NullSecurityContextRepository : 세션을 사용하지 않는 인증(JWT, OAuth2) 일 경우 사용하며 컨텍스트 관련 아무런 처리를 하지 않기 때문에 SecurityContextRepository의 도움을 받지 않는다

SecurityContextHolderFilter

  • SecurityContextRepository 를 사용하여 SecurityContext를 얻고 이를 SecurityContextHolder 에 설정하는 필터 클래스
  • SecurityContext를 세션에 저장하지 않는다
  • 인증이 지속되어야 하는지를 각 인증 메커니즘이 독립적으로 선택할 수 있게 하여 더 나은 유연성을 제공하고 HttpSession 에 필요할 때만 저장함으로써 성능을 향상시킨다

SecurityContext 생성, 저장, 삭제

  1. 익명 사용자
  • SecurityContextRepository 를 사용하여 새로운 SecurityContext 객체를 생성하여 SecurityContextHolder 에 저장 후 다음 필터로 전달
  • Authentication이 null이므로 AnonymousAuthenticationFilter 에서 AnonymousAuthenticationToken 객체를 SecurityContext 에 저장
  1. 인증 요청
  • SecurityContextRepository 를 사용하여 새로운 SecurityContext 객체를 생성하여 SecurityContextHolder 에 저장 후 다음 필터로 전달
  • UsernamePasswordAuthenticationFilter 에서 인증 성공 후 인증상태를 유지하기 위해 SecurityContext 에 UsernamePasswordAuthentication 객체를 SecurityContext 에 저장
  • SecurityContextRepository 를 사용하여 HttpSession 에 SecurityContext 를 저장(강제로 SecurityContextRepository.saveContext()를 실행)
  1. 인증 후 요청
  • SecurityContextRepository 를 사용하여 HttpSession 에서 SecurityContext 꺼내어 SecurityContextHolder 에서 저장 후 다음 필터로 전달
  • SecurityContext 안에 Authentication 객체가 존재하면 계속 인증을 유지한다
  1. 클라이언트 응답 시 공통
  • SecurityContextHolder.clearContext() 로 컨텍스트를 삭제 한다 (스레드 풀의 스레드일 경우 반드시 필요)

💡 현재는 SecurityContextPersistFilter 대신 SecurityContextHolderFilter를 사용한다

💡 커스텀 한 인증 필터를 구현할 경우 인증이 완료된 후 SecurityContext를 SecurityContextHolder에 설정한 후 SecurityContextRepository에 저장하기 위한 코드를 작성해야 한다

profile
높은 곳을 향해서

0개의 댓글