본문 바로가기

Language/Spring Security

DelegatingFilterProxy / FilterChainProxy

728x90

Filter (서블릿 필터)

  • 웹 애플리케이션에서 클라이언트의 요청(ServletRequest)과 서버의 응답(ServletResponse)을 가공하거나 검사하는 데 사용
  • 클라이언트의 요청이 서블릿에 도달하기 전이나 서블릿이 응답을 클라이언트에게 보내기 전 특정 작업을 수행
  • 필터는 서블릿 컨테이너(WAS)에서 생성되고 실행되고 종료
  • 필터의 doFilter() 메서드에서 chain.doFilter()의 이전, 이후 코드
    • 이전 코드 ⇒ 요청 처리 전 수행할 작업 (ServletRequest 수정)
    • 이후 코드 ⇒ 응답 처리 후 수행할 작업 (ServletResponse 수정)

DelegatingFilterProxy

  • 스프링에서 사용되는 특별한 서블릿 필터
  • 서블릿 컨테이너와 스프링 애플리케이션 컨텍스트 간의 연결 고리 역할
  • 서블릿 필터의 기능을 수행하는 동시에 스프링의 의존성 주입 및 빈 관리 기능과 연동되도록 설계된 필터
  • " springSecurityFilterChain"이라는 이름으로 생성된 빈을 ApplicationContext에서 찾아 요청을 위임
  • 실제 보안 처리를 수행하지 않음

 

  • 추가 설명
    • Spring Security는 필터 기반으로 요청을 처리하고 수행
    • 하지만 필터는 Servlet Container(WAS)를 기반으로 실행되고 종료 되어 SprinContainer와 관련이 없음
    • Filter에서는 Spring의 기능인 DI, AOP 같은 기능들을 사용할 수 없다는 의미
    • 즉, DelegatingFilterProxy는 필터를 기반으로 동작하는 Spring Security에서 Spring의 기능을 사용하기 위해 Servlet Container와 Spring Container를 연결하기 위해 등장

FilterChainProxy

  • springSecurityFilterChain의 이름으로 생성되는 필터 빈으로서 DelegatingFilterProxy로 부터 요청을 위임 받고 보안 처리 역할
    → DelegatingFilterProxy가 찾는 애 ⇒ FilterChainProxy
  • 내부적으로 하나 이상의 SecurityFilterChain 객체를 가지고 요청 URL 정보를 기준으로 적절한 SecurityFilterChain을 선택하여 Filter 호출
  • HttpSecurity를 통해 API 추가 시 관련 필터 추가
  • 사용자의 요청을 필터 순서대로 호출하여 보안 기능을 동작시키고 필요 시 직접 필터를 생성해서 기존의 필터 전, 후로 추가 가능

 

  • Spring Security가 초기화되고 서버 기동이 되면, 모든 요청은 최초로 DelegatingFilterProxy를 거쳐서 감 → 매 요청마다 거쳐서 감
  • DelegatingFilterProxy를 거치지 않고 Spring Security로 갈 수 있는 방법은 없음

SecurityFilterAutoConfiguration

  • DelegatingFilterProxyRegistrationBean 안에서 DEFAULT_FILTER_NAME으로 DelegatingFilterProxy 생성
@AutoConfiguration(after = SecurityAutoConfiguration.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(SecurityProperties.class)
@ConditionalOnClass({ AbstractSecurityWebApplicationInitializer.class, SessionCreationPolicy.class })
public class SecurityFilterAutoConfiguration {

	private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;

	@Bean
	@ConditionalOnBean(name = DEFAULT_FILTER_NAME)
	public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(
			SecurityProperties securityProperties) {
		DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
				DEFAULT_FILTER_NAME);
		registration.setOrder(securityProperties.getFilter().getOrder());
		registration.setDispatcherTypes(getDispatcherTypes(securityProperties));
		return registration;
	}
}

 

AbstractSecurityWebApplicationInitializer

  • DEFAULT_FILTER_NAME의 정의
public abstract class AbstractSecurityWebApplicationInitializer implements WebApplicationInitializer {
    public static final String DEFAULT_FILTER_NAME = "springSecurityFilterChain";
    ...
}

 

DelegatingFilterProxyRegistrationBean

  • targetBeanName = “springSecurityFilterChain”
  • this.targetBeanName의 이름을 WebbApplicationContext(스프링 컨테이너)에서 찾음
    • WebApplicationContext ⇒ 스프링의 Bean들이 관리되는 컨텍스트
public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistrationBean<DelegatingFilterProxy>
		implements ApplicationContextAware {
	...
	public DelegatingFilterProxyRegistrationBean(String targetBeanName,
			ServletRegistrationBean<?>... servletRegistrationBeans) {
		super(servletRegistrationBeans);
		Assert.hasLength(targetBeanName, "TargetBeanName must not be null or empty");
		this.targetBeanName = targetBeanName;
		setName(targetBeanName);
	}
	...
	@Override
	public DelegatingFilterProxy getFilter() {
		return new DelegatingFilterProxy(this.targetBeanName, getWebApplicationContext()) {
			@Override
			protected void initFilterBean() throws ServletException {
				// Don't initialize filter bean on init()
			}

		};
	}
	...
}

 

WebSecurityConfiguration

  • springSecurityFilterChain의 이름 FilterChainProxy 생성
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
	...
	@Bean(
        name = {"springSecurityFilterChain"}
  )
  public Filter springSecurityFilterChain() throws Exception {
      ...
  }
  ...
}

 

WebSecurity

  • performBuild() 메서드에서 FilterChainProxy 생성
public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements SecurityBuilder<Filter>, ApplicationContextAware, ServletContextAware {
	...
	protected Filter performBuild() throws Exception {
			...
      FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
      ...
      return (Filter)result;
  }
}

 


정리

  1. WebSecurityConfiguration에서 “springSecurityFilterChain”라는 이름의 Filter 생성
  2. WebSecurity의 performBuild() 메서드에서 SecurityFilterChain을 내장한 FilterChainProxy 생성
  3. DelegatingFilterProxy에서 springSecurityFilterChain라는 이름의 FilterChainProxy를 필터로 사용
728x90

'Language > Spring Security' 카테고리의 다른 글

폼 인증 - formLogin()  (0) 2024.07.15
사용자 정의 보안 설정하기  (0) 2024.07.15
WebSecurity / HttpSecurity  (0) 2024.07.15
SecurityBuilder / SecurityConfigurer  (0) 2024.07.15
프로젝트 생성 / 의존성 추가  (0) 2024.07.15