Filter 와 Interceptor
Interceptor 는 스프링 컨테이너 영역이므로 Spring 빈으로 등록이 가능하지만
Filter 는 서블릿 컨테이너의 영역이라서 Spring 의 빈으로 등록할 수 없다고 생각했다.
위 이미지와 같이 Filter 는 서블릿 컨테이너의 영역에서 존재하고 서블릿이 제공하는 기술이며
스프링 컨테이너의 영역과는 분리되어 있다.
하지만 개발을 하게 되면 Filter 를 Spring 빈으로 등록하여 사용하는걸 볼 수 있다.
서블릿 컨테이너에서 관리되는 DelegatingFilterProxy 가 서블릿 컨테이너와 스프링 컨테이너를
연결할 수 있는 프록시용 필터이다.
Spring Security Filter
Spring Security 는 위 이미지와 같이 서블릿 Filter 를 기반으로 서블릿을 지원한다.
클라이언트는 어플리케이션으로 요청을 전송하고 컨테이너는 서블릿과 여러 Filter 로
구성된 Filter Chain을 만들어 요청 URI Path 기반으로 사용자 요청(HttpServletRequest)을
처리한다.
단일 HttpServletRequest 와 HttpServletResponse 처리는 최대 한개의 서블릿이 담당한다.
DelegatingFilterProxy
Spring Security 는 사용하고자 하는 FilterChain들을 서블릿 컨테이너 기반의 필터 위에서 동작시키기 위해서
DelegatingFilterProxy 클래스를 사용한다. DelegatingFilterProxy는 표준 서블릿 필터를 구현하고 있어
서블릿 컨테이너에 등록되지만, Filter 를 구현하고 있는 Spirng Bean 에게 필터 작업을 위임한다.
위는 공식문서 에 나와 있는 FilterChainProxy 설명과 그림이다. 공식문서에서 보여주고 있는 FilterChain 이
ServletContainer 가 관리하는 필터이며 이는 ApplicationFilterChain 이다.
Spring 컨테이너에서 관리하는 빈이 아닌
서블릿 컨테이너(WAS)는 자체 표준 서블릿 필터를 사용해 구현하고 있으며,
내부에 위임대상(FilterChainProxy) 를 가지고 있다.
위 이미지를 보면 DelegatingFilterProxy는 Bean Filter0 을 찾아 실행하는데
Bean Filter 는 내부의 위임대상인 FilterChainProxy 가 된다.
이러한 FilterChainProxy 내부에서 Spring Security 와 관련된 일이 일어난다.
DelegatingFilterProxy 는 서블릿 컨테이너(WAS) 와 Spring 컨테이너의 다리 역할을 한다.
DelegatingFilterProxy 서블릿 컨테이너의 생명주기와 Spring 컨테이너의 ApplicationContext를
연결한다고 보면 된다.
DelegatingFilterProxy 는 Spring 컨테이너의 ApplicationContext 의 Bean으로 등록되어 있는
Filter 를 찾아 실행한다.
DelegatingFilterProxy 는 서블릿 필터이고, Spring IOC 컨테이너가 관리하는 FilterChainProxy(Bean)을
지니며 이 객체 안에서 Security 와 관련된 일을 한다.
FilterChainProxy 역시 처리를 위임하기 위해 SecurityFilterChain을 가지고 있다.
아래는 DelegatingFilterProxy 클래스의 doFilter 메서드이다.
DelegatingFilterProxy 의 doFilter()
DelegatingFilterProxy 는 서블릿 컨테이너와 스프링 컨테이너의 ApplicationContext를 연결하는데
findWebApplicationContext() 메서드를 통해 ApplicationContext를 가져온다.
그 후에 initDelegate(wac) 메서드를 통해 ApplicationContext에 저장된 Filter Bean 을 가져와
Filter에 저장 후 리턴한다. 내용은 아래 이미지와 같다.
DelegatingFilterProxy 의 initDelegate()
Filter에 저장 후 invokeDelegate() 메서드를 통해 Filter 의 doFilter 로 파라미터들을 전달한다.
DelegatingFilterProxy 의 invokeDelegate()
FilterChainProxy
위 내용에서 DelegatingFilterProxy가 서블릿 컨테이너와 스프링 컨테이너를 연결하는 다리이며
스프링 컨테이너의 ApplicationContext 를 연결한다고 했다.
ApplicationContext 에서 Bean으로 등록되어 있는 Filter(FilterChainProxy)들을 찾아 실행한다.
FilterChainProxy 는 Spring Security 가 제공하는 특별한 Filter 로 SecurityFilterChain을 통해
여러 Filter 로 위임할 수 있다.
참고 : https://godekdls.github.io/Spring%20Security/servletsecuritythebigpicture/
참고 : https://velog.io/@yaho1024/spring-security-delegatingFilterProxy