
서블릿 기반 애플리케이션일 경우, 엔드포인트에 요청이 도달하기 전에 중간에서 요청을 가로채 어떤 처리를 할 수 있는 포인트를 제공하는데 그것을 서블릿 필터 라고 한다.
- 서블릿 필터는 자바에서 제공하는 API
javax.servlet.Filter인터페이스를 구현한 서블릿 필터는 웹 요청을 가로채어 전처리를 할 수 있으며, 엔드포인트에서 전달되는 응답을 클라이언트에게 전달 하기 전 후처리를 할 수 있다.
서블릿 필터는 하나 이상의 필터들을 연결하여 필터 체인을 구성할 수 있다.
디스패쳐서블릿에 클라이언트의 요청이 전달되기 전에 필터 체인을 구성한 예.

서블릿 필터는 각각의 필터들이 doFilter()라는 메서드를 구현해야 하며, doFilter() 메서드 호출을 통해 필터 체인을 형성
보안과 관련된 작업을 추가한다.
DelegatingFilterProxy 와 FilterChainProxy 클래스는 Filter 인터페이스를 구현하므로 엄연한 서블릿 필터 역할을 한다. (조금 특별한 필터)⭐ DelegatingFilterProxy
- Spring Security 역시 Spring의 핵심인 ApplicationContext 를 이용한다.
- 서블릿 필터와 연결되는 Spring Security 만의 필터를 ApplicationContext에 Bean으로 등록한 후에 이 Bean들을 이용해서 보안과 관련된 여러가지 작업들을 처리하게 된다.
DelegatingFilterProxy가 Bean으로 등록된 Spring Security의 필터를 사용하는 시작점이라고 생각하면 된다.- 서블릿 컨테이너 영역의 필터와 ApplicationContext에 Bean으로 등록된 필터들을 연결해주는 브릿지 역할을 한다.
FilterChainProxy의 역할
⭐ FilterChainProxy
- Spring Security의 필터를 사용하기 위한 진입점
- FilterChainProxy 부터 Spring Security에서 제공하는 보안 필터들이 필요한 작업을 수행한다.
- URL 별로 여러개 등록 가능, 필터 체인이 있을때 어떤 것을 사용할 지 FilterChainProxy가 결정하며 가장 먼저 매칭된 필터 체인을 실행한다.
ex)
/api/**패턴의 Filter Chain이 있고,/api/messageURL 요청이 전송하는 경우
/api/**패턴과 제일 먼저 매칭되므로 디폴트 패턴인/**도 일치하나 가장 먼저 매칭되는/api/**패턴과 일치하는 필터 체인만 실행한다./message/**패턴의 필터 체인이 없는데/message/URL 요청 전송하는 경우
- 매칭되는 필터 체인이 없으므로 디폴트 패턴인
/**패턴의 필터 체인을 실행

(1) 사용자가 로그인 폼 등을 이용해 Username과 Password를 포함한 request를 Spring Security가 적용된 애플리케이션에 전송
사용자의 요청이 Filter Chain까지 들어오면 필터들 중에서 UsernamePasswordAuthenticationFilter가 해당 요청 받는다.
요청을 전달 받은 필터는 Username과 Password를 이용해 (2)와 같이 UsernamePasswordAuthenticationToken을 생성
Authentication 인터페이스를 구현한 구현 클래스이면 여기서 Authentication은 아직 인증이 되지 않음아직 인증되지 않은 Authentication을 가지고 있는 UsernamePasswordAuthenticationFilter는 (3)과 같이 해당 Authentication을 AuthenticationManager에게 전달
AuthenticationManager를 구현한 구현 클래스가 ProviderManager 이다.ProviderManager가 인증이라는 작업을 총괄하는 실질적인 매니저(4) ProviderManager로부터 Authentication을 전달 받은 AuthenticationProvider는 (5)와 같이 UserDetailsService를 이용해 UserDetails를 조회
UserDetails는 데이터베이스 등의 저장소에 저장된 사용자의 Username과 사용자의 자격을 증명해주는 크리덴셜인 Password, 사용자의 권한 정보를 포함하고 있는 컴포넌트UserDetails를 제공하는 컴포넌트가 바로 UserDetailsService 이다.UserDetailsService 는 (5)에서 처럼 사용자의 크리덴셜을 초함한 사용자의 정보 조회
저장소에서 조회한 사용자의 크리덴셜을 포함한 사용자의 정보를 기반으로 (7)과 같이 UserDetails를 생성한 후, 생성된 것을 다시 (8) AuthenticationProvider 에게 전달
UserDetails를 전달 받은 AuthenticationProvider 는 PasswordEncoder를 이용하여 UserDetails에 포함된 암호화 된 Password와 인증을 위한 Authentication 안에 포함된 Password가 일치하는지 검증
AuthenticationProvider는 인증된 Aithentication을 ProviderManager에게 전달(10)
Authentication은 인증을 위해 필요한 사용자의 로그인 정보를 가지지만,Authentication은 인증에 성공한 사용자의 정보 (Principal, Credential, GrantedAuthorities)를 가지고 있다.ProviderManager는 (11)과 같이 인증된 Authentication을 다시 UsernamePasswordAuthenticationFilter에게 전달한다.
(12)와 같이 SecurityContextHolder를 이용해 SecurityContext에 인증된 Authentication을 저장한다.

AuthorizationFilter 이다.AuthorizationFilter 는 (1) 과 같이 SecurityContextHolder로부터 Authentication을 획득AuthorizationManager에게 전달한다.AuthorizationManager는 권한 부여 처리를 총괄하는 매니저 역할을 하는 인터페이스RequestMatcherDelegationgAuthorizationManager는 AuthorizationManager를 구현하는 구현체 중 하나로 RequestMatcher 평가식을 기반으로 해당 평가식에 매치되는 AuthorizationManager 에게 권한 부여 처리를 위임하는 역할을 한다.RequestMatcherDelegationgAuthorizationManager 내부에서 매치되는 AuthorizationManager 구현 클래스가 있다면 해당 구현 클래스가 사용자의 권한을 체크 (3)AccessDeniedException이 throw되고 ExceptionTranslationFilter가 예외를 처리하게 된다.