참고 : https://docs.spring.io/spring-security/reference/servlet/architecture.html
- Servlet Container를 도식화한 그림
클라이언트 -> HttpServletRequest->FilterChain->DispatcherServlet->HttpServletResponse->FilterChain->클라이언트HttpServletRequest,HttpServletResponse를 수정할 수 있다.FilterChain이 각 필터를 순서대로 호출하고, 호출 할 때 respons, request 인스턴스를 주입한다. 
FilterChain 각 필터를 호출할 때, 바로 필터를 호출하는 것이 아니라 DelegatingFilterProxy를 호출한다. 개발자가 직접 작성하여 Bean으로 만든Bean Filter는 ApplicationContext에 존재하고 서블릿 컨테이너가 이를 가져오는 작업이 필요한데, 이 역할을 DelegatingFilterProxy가 한다.
DelegatingFilterProxy
:ApplicationContext에서 Bean Filter를 가져온 후, 실행시켜 모든 작업을 해당 필터에게 위임한다.
SpringSecurity를 support하는 서블릿들은 FilterChainProxy라는 빈 필터 안에 들어있다. FilterChainProxy는 Spring Security가 제공하는 많은 필터들,SecurityFilterChain의 delegate를 돕는 필터이다.
즉,
DelegatingFilterProxy>FilterChainProxy>SecurityFilterChain> 여러 개의 Filters...
그렇지만 왜
DelegatinFilterProxy에서 바로 delegating하지 않고FilterChainProxy를 한 번 더 거치는 걸까?
1. 디버깅에 용이 > Spring Security Sevlet의 시작점은 무조건 'FilterChainProxy'임으로 디버깅시 디버깅 포인트를 잡기 쉬움
2. 여러가지 다른 option들 사용 가능 ex) SecurityCOntext의 메모리 누수 피하기,HttpFirewall기능 등
3. SecurityFilterChain의 실행을 더 유연하게 제어할 수 있다. > Sevlet container에 의해서 제어되는 Filter들은 오직 URL에만 근거되어 Filter가 실행됨. 그렇지만FilterChainProxy에서는ReqeustMather를 사용하여HttpServletRequest내의 다향한 정보에 근거하여 Filter 실행을 결정할 수 있다.

FilterChainProxy가 이제 SecurityFilterChain 중에서 어떤 것을 실행할 지를 결정한다.
/api/messages/ 로 들어왔다면, SecurityFilterChain 𝙣과 바로 매치되므로 만약 뒤에 또 매치되는 필터가 있다하더라도 이 필터 체인 하나만 실행된다.SecuiryFilterChain 𝘯이 실행된다.SecurityFilterChain는 unique하다.SecurityFilterChain은 Filter를 가지고 있지 않을 수 있으며, 이 경우 해당 체인에 매치되는 요청에 대해서는 무시하게 된다.ExceptionTranslationFilter는 Security Filters 중의 하나이다.
ExceptionTranslationFilter가 예외를 catch해서 HTTP response에 해당 예외를 넣어 전송하는 등의 역할을 한다.1. 만일 user가 인증되어 있지 않거나 AuthenticationException 이 발생할 경우
: 인증 자체가 안 되어 있는 경우
ReqeustCache에 저장한다.AuthenticationEntrypoint에서 client에 credentails를 요청한다. (로그인 페이지로 redirect 시키거나 아님 HTTP response로 에러 넣어서 날리거나 하면 되는 듯?)2. 만일 AccessDeniedException이 발생한 경우
: 인가되지 않은 사용자일 경우 (자격이 없는 경우)
AccessDeniedHandler가 작동된다