스프링 시큐리티에서 사용자가 인증을 한 후 요청에 대해 계속 사용자의 인증을 유지하기 위해 사용되는 클래스
-> 인증을 유지 하기위해서 인증상태를 저장
인증 상태의 영속 메커니즘은 사용자가 인증 하게 되면 해당 사용자의 인증 정보의 권한이 SecurityContext에 저장되고, HttpSession을 통해 영속이 이뤄짐 (세션으로 부터 계속 요청이 이뤄진다.)

시큐리티가 인증에 대한 정보를 저장 / 저장하는 action을 치뤄야 한다.
SecurityContext 내부에 authentication 객체가 존재 해야 한다. / annoymous일 경우 -> 하나의 객체로 구분
구조
containsContext -> 현재 사용자를 위해 보안 컨텍스트가 저장소에 있는지 여부 조회
saveContext -> 인증 요청이 완료시 보안 컨텍스트 저장
loadDeferredContext -> 로딩을 지연시켜 필요 시점에 SecurityContext 가져옴 (Supplier를 실행 시켜 저장소로 부터 가져올 수 있도록)
HttpSessionSecurityContextRepository - 요청간 HttpSession에 보안 컨텍스트를 저장, 요청 컨텍스트 영속성 유지
RequestAttributeSecurityContextRepository - ServletRequest에 보안 컨텍스트 저장 -> 후속 요청시 컨텍스트 영속성 유지 X / 세션은 이러한 조건 외에는 계속 요청이 오더라도 저장, Request는 요청이 계속 변경된다.
NullSecurityContextRepository - 세션을 사용하지 않는 인증일 경우 사용자와 컨텍스트 관련 아무 처리 X (토큰으로만 저장)
DelegatingSecurityContextRepository - RequestAttributeSecurityContextRepository & HttpSessionSecurityContextRepository 동시 사용 가능
SecurityContextRepository를 사용하여 SecurityContext를 얻고 이를 SecurityContextHolder에 설정하는 필터 클래스 / 필터들 목록 중에서 상단에 SecurityContext를 상단에 위치 -> Authentication이 저장되어 있기 때문이다. 저장을 시켜주는 필터 역할이 SecurityContextHolderFilter 역할이다.
SecurityContextRepository.saveContext()를 강제로 실행 X, 사용자가 명시적 호출 SecurityContext를 저장가능, SecurityContextPersistenceFilter와 다른 장점 / Session에 저장을 하지 않는다.
인증이 지속되어야 하는지는 각 인증 메커니즘이 독립적 선택, 더 나은 유연성을 제공, HttpSession에 필요할때만 저장 / 인증이 지속 -> SecurityContext에 저장되어야 할 때 / 강제로 저장했을때 SideEffect 발생
익명 사용자 (무조건 새로운 객체를 생성 -> 저장하는 과정이 없기 때문)
SecurityContextRepository를 사용해서 새로운 SecurityContext객체를 생성, ((Authentication이 Null)이기 떄문에) SecurityContextHolder에 저장 후 필터로 전달
AnonymousAuthenticationFilter에서 AnonymousAuthenticationToken객체를 SecurityContext에 저장
인증 요청
SecurityContextRepository를 사용 -> 새로운 SecurityContext를 객체를 생성 SecurityContextHolder 저장 후 다음 필터로 전달
/인증 상태가 있기 때문에 인증을 진행
UsernamePasswordAuthenticationFilter에서 인증 성공 후 SecurityContext에 UsernamePasswordAuthentication 객체를 SecurityContext에 저장 (인증 상태를 유지 하기 위해)
인증 후 요청
SecurityContextRepository를 사용 -> HttpSession에서 SecurityContext를 꺼내어 SecurityContextHolder에 저장, 다음 필터로 전달 / 세션으로 부터 꺼내와서 실행
클라이언트 응답 시 공통
SecurityContextHolder.clearContext() 로 컨텍스트를 삭제 한다 (스레드 풀의 스레드일 경우 반드시 필요)

1) SecurityContextHolderFilter
-> SecurityContextRepository 에서 SecurityContext 를 로드하고 응답 시점에 Session 에 SecurityContext 를 저장하지 않는다
2) SecurityContextPersistanceFilter
-> SecurityContextRepository 에서 SecurityContext 를 로드하고 응답 시점에 Session 에 SecurityContext 를 저장
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityContext(securityContext -> securityContext
.requireExplicitSave(true)); // SecurityContext 를 명시적으로 저장할 것이지 아닌지의 여부 설정, 기본값은 true 이다
// true 이면 SecurityContextHolderFilter(명시적으로 SecurityFilter를 저장), false 이면 SecurityContextPersistanceFilter 가 실행된다
-> 현 버전에서는 두 필터가 공존, 상황에 따라 filter를 변경 가능
return http.build();
ecurityContextPersistanceFilter 은 Deprecated되어 있음
(직접 인증 필터를 만들 수 있음)
커스텀 한 인증 필터를 구현, 인증이 완료된 후 SecurityContext를 SecurityContextHolder에 설정한 후 securityContextRepository에 저장하기 위해 명시적으로 작성
securityContextHolderStrategy.setContext(context);
securityContextRepository.saveContext(context, request, response);
-> Session에 저장 할 수 있도록 구현체가 구성 됨
securityContextRepository는 HttpSessionSecurityContextRepository or DelegatingSecurityContextRepository를 사용