5. DelegatingFilterProxy → FilterChainProxy.doFilter() → FilterChain 복귀
Spring Security의 실제 Filter 체인 흐름을 오픈소스 코드 근거로 분석합니다.
전체 흐름 요약
- Tomcat의
ApplicationFilterChain이 각 Filter의 doFilter()를 호출 - Spring Security DelegatingFilterProxy가 등장하면, 내부적으로 Spring의 FilterChainProxy로 위임
- FilterChainProxy는 SecurityFilterChain(여러 Security Filter)들을 순차적으로 실행
- 모든 Security Filter가 끝나면, 원래의 FilterChain(ApplicationFilterChain)으로 복귀
- 남은 Filter가 있으면 계속 진행, 없으면 서블릿으로 이동
실제 코드 흐름 분석
1) Tomcat ApplicationFilterChain
// ApplicationFilterChain.java
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (pos < n) {
...
filter.doFilter(request, response, this); // 다음 Filter 호출
return;
}
// 모든 Filter가 끝나면 서블릿 호출
...
}
2) DelegatingFilterProxy
// DelegatingFilterProxy.java
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
...
invokeDelegate(delegateToUse, request, response, filterChain);
}
protected void invokeDelegate(Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
delegate.doFilter(request, response, filterChain); // 실제 FilterChainProxy로 위임
}
3) FilterChainProxy (Spring Security)
// FilterChainProxy.java
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
...
doFilterInternal(request, response, chain);
}
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
...
this.filterChainDecorator.decorate(reset, filters).doFilter(firewallRequest, firewallResponse);
}
// 내부 VirtualFilterChain
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (this.currentPosition == this.size) {
this.originalChain.doFilter(request, response); // 모든 Security Filter 끝나면 원래 FilterChain으로 복귀
return;
}
...
nextFilter.doFilter(request, response, this); // 다음 Security Filter 호출
}
시퀀스 다이어그램
sequenceDiagram
participant FilterChain as ApplicationFilterChain
participant SecurityProxy as DelegatingFilterProxy
participant SecurityChain as FilterChainProxy
participant SecurityFilters as SecurityFilterChain
participant Servlet
FilterChain->>SecurityProxy: doFilter()
SecurityProxy->>SecurityChain: doFilter()
SecurityChain->>SecurityFilters: doFilter() (여러 Security Filter)
SecurityFilters-->>SecurityChain: 완료
SecurityChain-->>FilterChain: doFilter() (원래 FilterChain 복귀)
FilterChain->>Servlet: service()
설계 의도 및 이유
- Tomcat과 Spring Security의 결합을 느슨하게 유지하기 위해 DelegatingFilterProxy를 사용
- Spring Security의 FilterChainProxy는 여러 보안 필터를 유연하게 조합/관리
- 모든 보안 처리가 끝나면, 원래의 FilterChain(ApplicationFilterChain)으로 복귀하여 서블릿 처리 흐름을 보장
- 이 구조 덕분에 보안 로직과 웹 컨테이너의 결합도가 낮아지고, 확장성과 테스트 용이성이 높아짐
← 이전: 4. ApplicationFilterChain → DelegatingFilterProxy.doFilter() | 다음: 6. (작성 예정)