[ODOP] 87일차 - 스프링 시큐리티 아키텍처:인증 요청 흐름
![[ODOP] 87일차 - 스프링 시큐리티 아키텍처:인증 요청 흐름](/content/images/size/w1200/2023/08/-----2023-08-01----10.29.26-30.png)
![](https://blog.pollra.com/content/images/2023/08/-----2023-09-01----4.09.22-1.png)
- Filter 를 기준으로
- 위쪽은 Security 의 초기화 과정이다
- 아래쪽은 각 Filter 의 처리 과정이다
인증 요청 흐름
-
사용자가 인증을 시도
가정 : 서버가 켜진 뒤 로그인을 최초 시도, 이미 가입된 사용자, 정상적인 로그인 요청
-
Controller 의 라이프사이클이 실행되기 이전, DelegatingFilterProxy 가 먼저 해당 요청을 수신
-
DelegatingFilterProxy 는 springSecurityFilterChain 이라는 이름을 가진 bean(FilterChainProxy) 에게 요청을 위임
-
인증 저장소 필터(SecurityContextPersistenceFilter)
사용자가 로그인한적이 있으면 해당 Authentication 을 SecurityContext 에 넣어주고, 만약 처음 로그인 하는 사용자라면 요청 정보(Authentication)를 새로 저장하는 역할을 수행
실질적인 인증 기능을 수행하는 것은 아니며 추후 FilterChain 을 통해 인증 절차가 수행된다.
첫 로그인 인증 저장소 필터 흐름
- loadContext
이전에 SecurityContext 가 생성되어 session 에 저장된 이력이 있는지 체크
(하지만 1번의 가정에 따라 현재는 session 에 저장된 이력이 없으므로 다음 로직을 수행) - create securityContext
새로운 로그인의 경우 새로운 securityContext 를 생성
(해당 로직이 수행되어 새로운 securityContext 를 생성) - save session
생성된 securityContext 를 SecurityContextHolder 에 저장
securityContext 안에는 사용자의 요청 정보를 담은 Authentication 인스턴스를 담는다 - 최종적으로 모든 로직이 수행되고 클라이언트에게 응답하는 시점에 SecurityContextHolder.clear() 를 수행하여 SecurityContext 를 비운다
[?] 인증 후에도 Spring lifecycle 안에서 SecurityContaxtHolder 정보 꺼내 쓸 수 있던데요?
해당 동작이 가능한 이유는 클라이언트에 응답하기 직전에 비워주기 때문.
(이 시점에서는 라이프사이클의 모든 로직이 끝나있음)
따라서 스프링의 라이프사이클 내부에서 사용하는 것에는 문제가 없다
![](https://blog.pollra.com/content/images/2023/08/-----2023-09-01----4.18.15.png)
- 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
로그인 프로세스 흐름
-
유저의 로그인 요청을 Authentication 객체의 인스턴스로 만든다
-
authentication 정보를 Authentication Manager 의 인증 처리자 에게 위임
-
만들어진 정보를 이용해 인증 처리자(Authentication Provider) 는 UserDetailsService 를 동작시키며 핵심적인 인증 로직을 수행
-
인증에 성공하면 성공한 정보를 Authentication 의 인스턴스에 담고 SecurityContextHolder 의 SecurityContext 에 담는다
이 때 SecurityContext 는 SecurityContextPersistenceFilter 에서 만든 Authentication 이 담긴 메모리 경로와 같은 공간에 저장
해당 로직의 인증 시점에 SessionManagementFilter 의 동시 세션 제어를 위한 흐름을 타게 된다.
동시 세션 제어 흐름
-
ConcurrentSession
지금 사용자와 동일한 계정으로 이전에 로그인한 기록이 있는 경우, 설정에 따라 Exception 을 발생
(예를들어 동시 세션 제어 에 중복 로그인 가능 횟수가 1이라면 로그인 재시도를 할 경우 exception 발생) -
SessionFixation
인증을 시도하기 이전의 쿠키를 삭제하고 새로운 쿠키를 생성
-
Register SessionInfo
사용자의 세션 정보가 등록