왜? 필터체인?

뾰족머리삼돌이·2024년 10월 27일
0

Spring Security

목록 보기
11/16

WAS를 사용하는 Spring 애플리케이션을 가정해보자.
클라이언트가 전송한 요청은 WAS(=Servlet Engine, ex: tomcat )를 거쳐 DispatcherServlet, Controller로 전달된다.

필터와 인터셉터는 요청이 WAS와 Controller로 진입할 때 동작하며, 공통적으로 처리되어야할 작업을 처리한다.
디자인패턴으로 생각해보면 프록시패턴이 사용된다고 볼 수 있다. 실제 작업 호출을 가로채 공통적인 작업을 처리하기 때문이다.

필터는 요청이 WAS에 진입하는 시점, 조금 더 정확히는 DispatcherServlet에 진입하는 전후로 동작한다.
Spring 작업영역 외부에서 동작하기에 인터셉터보다 더 전역적인 작업처리(ex : 문자인코딩이나 CORS, CSRF보안) 에 용이하다.

인터셉터는 요청이 DispatcherServlet을 거쳐 Controller에 진입하는 전후로 동작한다.
Spring 작업영역 내부에서 동작하기에 서비스 동작 전, 공통적으로 처리될 작업처리(ex: 사용자 인증과 인가, 로깅)에 용이하다.

그런데 Spring Security는 왜?

앞서 사용자 인증과 인가작업을 처리하는데 적절한 위치는 인터셉터라고 소개했다. 그런데 의아하게도 Spring Security는 필터 기반으로 동작한다. 이번 포스팅에서는 왜? 그런지에 대해 고민한 내용을 적어볼 예정이다.

Spring Security 아키텍처에서 소개했던 공식문서의 필터체인 이미지를 가져왔다.

클라이언트가 보낸 요청은 서블릿으로 진입하기 이전에 필터체인을 거치게되고, 그 과정에서 인증과 인가 그리고 보안 등의 작업이 이뤄진다.
이는 필터체인, 즉 필터로 이루어진 연쇄작업을 거치면서 필터조건에 부합되는 경우, 요청에 대한 작업을 처리한다.

어떻게 필터에서 Bean을 쓰는걸까?

조금 더 자세히 들어가면 Security 관련 동작을 수행하는 필터들은 SecurityFilterChain이라는 별도의 필터체인에서 작업을 수행한다.

신기한 점은 Spring Security의 필터는 Spring 작업영역 외부에서 동작함에도 Bean으로 등록하고 주입받을 수 있다.
이는 위 이미지에 표시된 DelegatingFilterProxy 라는 클래스의 동작을 알아볼 필요가 있다.

Spring Boot 애플리케이션이 처음 구동되면 WebApplicationContext를 생성하고, 초기 Bean들을 등록한다.
Spring Security를 사용한다면, 이 과정에서 생성되는 Bean 중에 springSecurityFilterChain 이라는 Bean이 존재한다.

public DelegatingFilterProxy(String targetBeanName, @Nullable WebApplicationContext wac) {
	Assert.hasText(targetBeanName, "Target Filter bean name must not be null or empty");
	setTargetBeanName(targetBeanName); // targetBeanName == springSecurityFilterChain
	this.webApplicationContext = wac;
	if (wac != null) {
		setEnvironment(wac.getEnvironment());
	}
}

springSecurityFilterChainDelegatingFilterProxy에 감싸진 형태로 생성되며, 그 과정에서 WebApplicationContext 에 대한 참조 또한 기록된다.

즉, DelegatingFilterProxySecurityFilterChainWebApplicationContext에 대한 참조를 가진다.

실제 필터동작 수행은 SecurityFilterChain 에서 이뤄지며,
DelegatingFilterProxy이 먼저 호출되므로 Bean으로 등록되고 주입 받을 수 있다.

그래서 필터? 왜?

다시 본론으로 돌아와서 Spring Security는 왜 필터 기반으로 동작할까?
먼저, 필터는 WAS 외부에 존재한다는 점을 기억해야한다. 다르게 표현하자면 WAS에 종속되지 않는 것이다.

기본 내장되어 사용되는 Tomcat외에도 Jetty, Undertow 등 다양한 WAS들이 존재한다.
Spring 애플리케이션들은 설정을 통해 이러한 WAS들을 변경할 수 있는데, 필터는 WAS에 종속되지 않으므로 이러한 WAS 변경에 자유롭다는 장점을 가진다.


하지만, 인터셉터 또한 Spring MVC를 사용한다면 일관된 사용방식을 제공하므로 WAS 변경에 영향을 받지않는다.
조금 생각해보면 Spring MVC를 사용한다면 라는 조건이 들어감을 눈치챌 수 있다. 즉, 인터셉터는 웹 프레임워크에 종속된다.

반면, 필터는 WAS 외부에 존재하므로 웹 프레임워크와도 독립적으로 동작한다.
조금 더 정확하게는 Spring Security가 Spring Framework위에 구축되었기 때문에 Spring Framework는 필요로하지만,
Spring Framework와의 통합을 제공하는 웹 프레임워크에 독립적이다.

예를들어 Spring Web MVC가 아닌, JSF나 Apache Struts 와도 Spring Security를 사용할 수 있다.

웹 프레임워크 독립성 외에도 보안처리와 함께 일관된 위치에서 처리됨을 보장되는 장점도 있다

0개의 댓글