
Spring Security는 인증, 인가 및 일반적인 공격에 대한 보호 기능을 제공하는 프레임워크
참이라는 근거가 있는 무언가를 확인하거나 확증하는 행위
리소스에 대한 접근 권한 및 정책을 지정하는 기능

1️⃣ 사용자가 로그인 정보와 함께 인증 요청
2️⃣ AuthenticationFilter가 요청을 가로채고, 로그인 정보를 가지고 UsernamePasswordAuthenticationToken의 인증용 객체 생성
3️⃣ AuthenticationManager의 구현체인 ProviderManager에게 생성한 UsernamePasswordAuthenticationToken을 전달
4️⃣ AuthenticationManager가 등록된 AuthenticationProvider들을 조회해 인증 요구
5️⃣ UserDetailsService에 로그인 정보 전달
6️⃣ DB에서 찾은 사용자 정보인 UserDetails 객체 생성
7️⃣ AuthenticationProvider들은 UserDetails를 전달받고 사용자 정보 비교
8️⃣ 인증이 완료되면 권한 등의 정보를 담은 Authentication 객체 반환
9️⃣ 다시 최초의 AuthenticationFilter에 Authentication 객체 반환
🔟 Authentication 객체를 SecurityContext에 저장
✔️ 사용자 정보를 저장한다는 것은 Spring Security가 전통적인 세션-쿠키 기반의 인증 방식을 사용

Servlet Filter 기반
HttpServletRequest를 처리해야 하는 Filter 및 Servlet을 포함하는 FilterChain 생성Servlet은 DispatcherServlet Servlet이 HttpServletRequest와 HttpServletResponse 처리를 담당한다Filter는 여러 개를 사용할 수 있다, Servlet과 다운스트림 Filter의 실행을 막는다. 이 경우엔 Filter에서 HttpServletResponse를 작성한다Servlet과 여러 Filter로 HttpServletRequest나 HttpServletResponse를 수정한다Filter는 다운스트림 Filter와 Servlet에만 영향을 미치기 때문에 각 Filter가 호출되는 순서가 매우 중요하다. 
스프링은
DelegatingFilterProxy라는 필터 구현을 제공하여Servlet컨테이너의 라이프사이클과ApplicationContext간의 연결을 가능하게 한다.
Servlet 컨테이너는 자체 표준을 사용하여 Filter를 등록할 수 있지만 Spring Bean은 알아차리지 못한다.DelegatingFilterProxy는 표준 Servlet 컨테이너 메커니즘을 통해 등록할 수 있지만 모든 작업을 Filter를 구현하는 Spring Bean에 위임ApplicationContext에서 Bean Filter를 찾은 후 호출 
스프링 시큐리티가 제공하는 특별한
Filter로,SecurityFilterChain을 통해 여러Filter인스턴스로 위임 가능
FilterChainProxy는 Bean이기 때문에 DelegatingFilterProxy로 감싸져있다.
FilterChainProxy가 요청에 사용할Filter를 선택할 때 사용
SecurityFilterChain에 있는 Security Filter는 전형적인 Bean이지만, DelegatingFilterProxy가 아닌 FilterChainProxy로 등록된다.FilterChainProxy을 직접 서블릿 컨테이너에 등록하거나 DelegatingFilterProxy에 등록하면 좋은 점FilterChainProxy부터 디버그해 보는 것이 좋다.FilterChainProxy는 스프링 시큐리티의 중심이기 때문에 필수로 여겨지는 작업을 할 수 있다.SecurityFilterChain을 언제 실행해야 할 지 유연하게 결정할 수 있다.Filter들을 결정FilterChainProxy는 RequestMatcher 인터페이스를 사용하면 HttpServletRequest에 있는 어떤 것으로도 실행 여부를 결정할 수 있다.SecurityFilterChain을 결정할 때 FilterChainProxy를 사용한다.
/api/messages/를 요청하면 SecurityFilterChain의 /api/** 패턴과 제일 먼저 매칭되므로, SecurityFilterChain도 일치하긴 하지만 SecurityFilterChain만 실행/message/로 요청하면 SecurityFilterChain과 매칭되지 않기 때문에 FilterChainProxy는 계속 다른 SecurityFilterChain을 시도SecurityFilterChain을 실행SecurityFilterChain은 고유하면서 격리된 설정을 가질 수 있다.Filter 0개 설정도 가능SecurityFilterChain API를 사용해서 FilterChainProxy에 추가
ExceptionTranslationFilter는AccessDeniedException을 해석하고AuthenticationException을 HTTP 응답으로 바꿔준다.
ExceptionTranslationFilter는 FilterChainProxy에 하나의 Security Filter로 추가
ExceptionTranslationFilter는 FilterChain.doFilter(request, response)를 호출해서 애플리케이션의 나머지 로직을 실행AuthenticationException이 발생했다면, 인증을 시작SecurityContextHolder를 비운다.RequestCache에 HttpServletRequest를 저장RequestCache로 기존 요청 처리를 이어간다.AuthenticationEntryPoint는 클라이언트에 credential을 요청할 때 사용AccessDeniedException이면, 접근을 거부AccessDeniedHandler에서 처리애플리케이션에서
AuthenticationException나AccessDeniedException을 던지지 않으면ExceptionTranslationFilter는 동작하지 않는다.
https://godekdls.github.io/Spring%20Security/servletsecuritythebigpicture/
https://docs.spring.io/spring-security/reference/5.6/index.html