DelegatingFilterProxy
와 FilterChainProxy
가 어떻게 생성되고 이 두 객체가 자동 설정에 의한 기본 보안 적용 기능 과정에서 어떻게 쓰이는지 흐름을 파악한다.
우선 Filter는 spring을 사용한다면(더 정확히는 servlet container를 사용하는 웹 애플리케이션을 개발한다면) 다들 익숙한 개념이다.
서블릿 필터는 WAS 컨테이너에서 생성되고 실행되고 종료된다. 서블릿 필터는 웹 애플리케이션에서 클라이언트의 요청과 서버의 응답을 가공하거나 검사하는데 사용된다.
이러한 특징으로 서블릿 필터는 클라이언트의 요청이 서블릿에 도달하기 전, 서블릿이 응답을 클라이언트에게 보내기 전에 특정 작업을 수행할 수 있다.
보통 Filter
들은 이 Filter
인터페이스를 구현한 구현체로서 doFilter
메소드를 override하여 구현할 때,
var3(FilterChain).doFilter
메소드를 호출하는데,
이 이전 코드는 요청 처리 전에 수행하는 작업, 이 이후 코드는 응답 처리 전에 수행하는 작업을 명시하여 Filter
인터페이스를 구현한다.
DelegatingFilterProxy
는 Filter
인터페이스를 구현한 클래스다.
원래 Filter
는 Spring
기술이 아닌 WAS 컨테이너에서 사용하는 서블릿 기술이다. 따라서 Spring
의 IoC 컨테이너를 활용한 DI, AOP 등을 활용할 수 없다.
하지만 DelegatingFilterProxy
는 스프링에서 사용되는 특별한 서블릿 필터로, 서블릿 필터의 기능을 수행하는 동시에 스프링의 의존성 주입 및 빈 관리를 할 수 있도록 설계된 필터다.
즉, Filter
를 구현한 클래스를 빈으로 생성해서 필터의 기능도 하지만, spring의 DI, AOP 같은 기능도 활용할 수 있도록 한 것이다.
DelegatingFilterProxy
는 "springSecurityFilterChain" 이름의 빈을 ApplicationContext(스프링 컨테이너)에서 찾아서 보안 요청 처리를 하도록 클라이언트 요청을 전달(위임)한다.
FilterChainProxy
는 "springSecurityFilterChain" 이름으로 생성되는 필터 빈이다.
내부적으로 하나 이상의 SecurityFilterChain
객체들을 가지고 있다. 이는 지난 번에 살펴본 적이 있다.
FilterChianProxy
는 요청 URL을 기준으로 현재 요청을 처리할 적절한 SecurityFilterChain
을 선택하여 보안 처리를 하도록 한다.
FilterChainProxy
는 클라이언트의 요청을 필터 순서대로 호출하여 보안 처리를 하고, 필요하다면 우리가 직접 필터를 추가해서 존재하는 필터의 전, 후로 추가할 수도 있다.
FilterChainProxy
는 맨 마지막 필터인 인가 처리를 담당하는 필터(AuthorizationFilter
)까지 예외가 발생하지 않으면 요청을 서블릿으로 전달하게 된다.
HttpSecurity
의 api를 호출하면서(ex, csrf메소드 등) 필터를 생성하는데, 이는 HttpSecurity
가 SecurityConfigurer
들을 담고 있다가 build
메소드를 호출하면서 필터들을 생성하고 이 필터들을 가지고 있는 SeucrityFilterChain
을 빈으로 등록하는 과정의 일부다.(저번 시간에 본 적 있다.)
서버를 실행하면 자동 설정에 의해 SecurityFilterAutoConfiguration
클래스에 진입하게 된다.
SecurityFilterAutoConfiguration
의 securityFilterChainRegistration
메소드는 빈 생성 메소드로 DelegatingFilterProxyRegistrationBean
을 생성하고 DelegatingFilterProxyRegistrationBean
빈을 등록하고 있다.
DelegatingFilterProxyRegistrationBean
을 생성할 때 상수값을 파라미터에 전달하고 있는데 이 값은 "springSecurityFilterChain"이다.
DelegatingFilterProxy
가 "springSecurityFilterChain" 이름의 빈을 찾는다고 아까 이야기 한 적이 있다.
DelegatingFilterProxyRegistrationBean
을 보면 생성자의 targetBeanName 파라미터에 전달한 "springSecurityFilterChain"값을 보관하고 있는 것을 알 수 있다.
DelegatingFilterProxyRegistrationBean
빈은 DelegatingFilterProxy
빈을 생성한다.
DelgatingFilterProxy
를 생성할 때 targetBeanName값을 전달하는데 이 값이 "springSecurityFilterChain"이다.
addRegistration
메소드를 통해 addFilter
메소드를 호출하는데, 이때 DelegatingFilterProxy
를 서블릿 필터로 등록한다(서블릿 컨테이너에 등록되는 것이다).
그 다음에 이전 시간부터 살펴봤던 HttpSecurity
객체를 통해 보안 필터들을 들고있는 SecurityFilterChain
빈을 생성하는 과정을 거친다.
그리고 WebSecurityConfiguration
에서 WebSecurity
의 build
메소드를 통해 SecurityFilterChain
를 보관하는 FilterChainProxy
를 생성하고 FilterChainProxy
를 빈으로 등록한다.
FilterChainProxy
를 빈으로 등록할 때 그 이름을 "springSecurityFilterChain"으로 등록한다.