스프링 시큐리티는 필터를 기반으로 인증, 인가 업무를 처리한다
사용자 요청은 서블릿 필터로 처리된다.
그런데 Filter(서블릿 필터)는 서블릿 컨테이너가 관리한다.
그래서 Spring Bean(스프링 시큐리티의 필터)을 주입받는 것이 어렵다
(서블릿 필터와 스프링 시큐리티의 필터를 서로 다른 컨테이너에서 관리하기 때문이다.)
스프링 시큐리티는 이 문제를 어떻게 처리할까?
서블릿 필터
DelegationFilterProxy를 만든다.
서블릿 필터DelegationFilterProxy는 서블릿 필터의 동작을 스프링 빈(스프링 시큐리티의 필터들)로 위임한다.
실제 보안 처리는 스프링 빈으로 생성된 필터들에 의해서 처리된다.
DelegationFilterProxy는 org.springframework.web.filter 패키지라 스프링 시큐리티가 없어도 사용할 수 있는 것으로 보인다. 스프링 인터셉터 대신 필터가 필요하면 이걸 사용해서 만들 수 있는 것으로 보인다.
DelegatingFilterProxy class의 code를 간단하게 보고 어떻게 작동하는 지 살펴보자
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
/*
기타코드는 생략
initDelegate를 호출해 위임할 객체를 찾는다.
initDelegate는 WebApplicationContext를 찾아가서 이름이 'springSecurityFilterChain'인 빈을 찾아온다
'springSecurityFilterChain'이 바로 스프링 시큐리티에서 보안업무를 처리하는 필터들이다.
*/
delegateToUse = initDelegate(wac);
this.delegate = delegateToUse;
invokeDelegate(delegateToUse, request, response, filterChain); // delegate
}
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 필터가 해야할 보안 업무를 스프링시큐리티의 필터로 위임한다
delegate.doFilter(request, response, filterChain);
}
서블릿 필터 DelegationFilterProxy는 springSecurityFilterChain이라는 이름을 가진 빈에게 필터업무를 위임한다,
springSecurityFilterChain라는 이름을 가진 빈은 무엇일까?
정답은 FilterChainProxy이다.
FilterChainProxy는 스프링 시큐리티의 초기화과정에서 SecurityFilterChain들을 주입받는다.
SecurityFilterChain는 보안업무를 수행할 필터들을 가지고 있다.
사용자 요청에 대해서 FilterChainProxy가 적절한 SecurityFilterChain를 사용하여 적절한 보안 업무를 수행한다.
즉 이 과정을 정리하자면
1. 서블릿 컨테이너에 의해서 필터들이 실행된다.
2. 서블릿 컨테이너가 DelegationFilterProxy를 실행한다.
3. DelegationFilterProxy는 FilterChainProxy에게 delegate한다.
4. FilterChainProxy는 SecurityFilterChain을 통해서 필터업무를 수행한다.
SecurityFilterAutoConfiguration라는 이름을 가진 빈은 SecurityFilterAutoConfiguration가 자동으로 설정해준다. (필터 등록도 해주는 것 같다.)
AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME가springSecurityFilterChain라는 Bean 이름을 가지고 있다.
FilterChainProxy와 SecurityFilterChain의 생성 및 초기화는 Spring Security 초기화글에서 소개하겠다.