[ODOP] 87일차 - 스프링 시큐리티 아키텍처:인증 요청 흐름

[ODOP] 87일차 - 스프링 시큐리티 아키텍처:인증 요청 흐름
  • Filter 를 기준으로
    • 위쪽은 Security 의 초기화 과정이다
    • 아래쪽은 각 Filter 의 처리 과정이다

인증 요청 흐름

  1. 사용자가 인증을 시도

    가정 : 서버가 켜진 뒤 로그인을 최초 시도, 이미 가입된 사용자, 정상적인 로그인 요청

  2. Controller 의 라이프사이클이 실행되기 이전, DelegatingFilterProxy 가 먼저 해당 요청을 수신

  3. DelegatingFilterProxy 는 springSecurityFilterChain 이라는 이름을 가진 bean(FilterChainProxy) 에게 요청을 위임

  4. 인증 저장소 필터(SecurityContextPersistenceFilter)

    사용자가 로그인한적이 있으면 해당 Authentication 을 SecurityContext 에 넣어주고, 만약 처음 로그인 하는 사용자라면 요청 정보(Authentication)를 새로 저장하는 역할을 수행
    실질적인 인증 기능을 수행하는 것은 아니며 추후 FilterChain 을 통해 인증 절차가 수행된다.

첫 로그인 인증 저장소 필터 흐름

  1. loadContext
    이전에 SecurityContext 가 생성되어 session 에 저장된 이력이 있는지 체크
    (하지만 1번의 가정에 따라 현재는 session 에 저장된 이력이 없으므로 다음 로직을 수행)
  2. create securityContext
    새로운 로그인의 경우 새로운 securityContext 를 생성
    (해당 로직이 수행되어 새로운 securityContext 를 생성)
  3. save session
    생성된 securityContext 를 SecurityContextHolder 에 저장
    securityContext 안에는 사용자의 요청 정보를 담은 Authentication 인스턴스를 담는다
  4. 최종적으로 모든 로직이 수행되고 클라이언트에게 응답하는 시점에 SecurityContextHolder.clear() 를 수행하여 SecurityContext 를 비운다

[?] 인증 후에도 Spring lifecycle 안에서 SecurityContaxtHolder 정보 꺼내 쓸 수 있던데요?

해당 동작이 가능한 이유는 클라이언트에 응답하기 직전에 비워주기 때문.
(이 시점에서는 라이프사이클의 모든 로직이 끝나있음)

따라서 스프링의 라이프사이클 내부에서 사용하는 것에는 문제가 없다

  • code-110 : filter chain 을 실행했던 부분. 모든 filter chain 이 끝나면 다시 이 부분으로 돌아오지만 코드(try)의 마지막부분이기 때문에 finally 구문이 실행.
  • code-113 : 저장된 securityContextHolder 안의 SecurityContext 를 빼오는 것을 확인 가능. 이는 로그인 완료된 사용자의 context 를 session 에 저장하기 위해 빼오는 동작
  • code-115 : SecurityContextHolder 를 초기화. 이 때는 Client 에게 응답하기 직전의 상태이므로 SecurityContextHolder 가 초기화 되는것과는 상관이 없다.
  • code-116 : code-113 에서 빼두었던 SecurityContext 를 session 에 저장

LogoutFilter

특별히 Logout 요청이 들어오지 않는 이상 동작하지 않는 Filter

로그인 요청의 경우 SecurityContextPersistenceFilter 에서 바로 UsernamePasswordAuthenticationFilter 로 넘어간다

UsernamePasswordAuthenticationFilter

인증에 대한 핵심적인 로직이 동작하는 filter

로그인 프로세스 흐름

  1. 유저의 로그인 요청을 Authentication 객체의 인스턴스로 만든다

  2. authentication 정보를 Authentication Manager 의 인증 처리자 에게 위임

  3. 만들어진 정보를 이용해 인증 처리자(Authentication Provider) 는 UserDetailsService 를 동작시키며 핵심적인 인증 로직을 수행

  4. 인증에 성공하면 성공한 정보를 Authentication 의 인스턴스에 담고 SecurityContextHolder 의 SecurityContext 에 담는다

    이 때 SecurityContext 는 SecurityContextPersistenceFilter 에서 만든 Authentication 이 담긴 메모리 경로와 같은 공간에 저장

해당 로직의 인증 시점에 SessionManagementFilter 의 동시 세션 제어를 위한 흐름을 타게 된다.

동시 세션 제어 흐름

  1. ConcurrentSession

    지금 사용자와 동일한 계정으로 이전에 로그인한 기록이 있는 경우, 설정에 따라 Exception 을 발생
    (예를들어 동시 세션 제어 에 중복 로그인 가능 횟수가 1이라면 로그인 재시도를 할 경우 exception 발생)

  2. SessionFixation

    인증을 시도하기 이전의 쿠키를 삭제하고 새로운 쿠키를 생성

  3. Register SessionInfo

    사용자의 세션 정보가 등록