학습Spring Security의 필터에 대해 알아보자
인증 로직 파악 Spring Security는 서블릿 필터 기반으로 동작합니다. 따라서 제대로 이해하기 위해서 필터 체인의 구조와 역할을 파악해야 합니다. 클라이언트가 서버로 HTTP 요청을 보내면, 서블릿 컨테이너는 다음과 같은 흐름으로 요청을 처리하게 됩니다. 1. 요청 URI를 기반으로 어떤 자원을 처리할지 결정 2. 해당 요청을 처리할 필터 체인 생성 3. 필터들을 순서대로 실행 4. 최종적으로 서블릿 실행 - Spring MVC에서는 DispatcherServlet이 해당 역할을 수행합니다. Client → Filter Chain → DispatcherServlet → Controller 필터의 핵심 역할 필터는 서블릿에 도달하기 전 단계에서 요청/응답을 가로채어 다양한 작업을 수행합니다. 핵심 역할은 크게 두 가지로 분류됩니다. 필터는 다음 필터 또는 서블릿으로 요청을 전달하지 않고 중단할 수 있습니다. 대표적인 예로 인증되지 않은 사용자 요청 차단, 권한이 없는 사용자 접근 제한인 경우가 있습니다. 이 경우 필터는 직접 응답을 생성하여 클라이언트에게 반환합니다 Client → Filter Chain → Filter(차단) - Response 반환 필터는 HttpServletRequest 와 HttpServletResponse 가공이 가능합니다. 예를 들어 JWT 토큰 파싱 후 사용자 정보를 추가, 요청 헤더 수정, 응답 헤더 추가(CORS, 보안 헤더 등)이 있습니다. Client → Filter Chain → Filter (가공) → 다음 Filter → Servlet 필터 체인의 특징 필터 체인에는 여러 개의 필터가 존재할 수 있습니다. LoggingFilter → JwtAuthenticationFilter → AuthorizationFilter → DispatcherServlet 필터 체인에 추가된 필터 순서에 따라서 동작 결과가 달라지기 때문에 주의해야 한다. 예를 들어 인증 필터보다 권한 필터가 먼저 실행되면 인증 정보가 없는 상태에서 오류가 발생하기 때문입니다. 필터 체인은 체인 기반으로 실행하는 구조로 동작하여 이러한 구조 덕분에 요청 전/후 처리가 가능하고, AOP와 유사한 흐름 제어가 가능합니다. 아래는 필터가 실행되는 코드입니다. 필터 성능 필터는 요청마다 실행되므로 필터 체인이 길어질수록 처리하기 위한 비용이 증가합니다. 불필요한 필터 추가는 성능 저하로 이어지며, 반드시 필요한 필터만 유지해야 합니다. 필터에서는 DB 접근을 최소화하고, 복잡한 로직을 지양하며, 캐시를 활용하는 방법도 좋습니다. Spring Security 에서 필터란 Spring Security는 필터 구조 위에 인증, 보안, 세션 관리, CSRF 보호 같은 보안 기능을 추가합니다. 즉 내부적으로 수십 개의 필터 체인을 구성하여 동작합니다. 예를 들어 'UsernamePasswordAuthenticationFilter', 'BearerTokenAUthenticationFilter' 등이 있습니다. DelegatingFilterProxy DelegatingFilterProxy는 서블릿 컨테이너와 스프링 컨테이너를 연결하는 '다리' 역할을 합니다. 기본적으로 서블릿 컨테이너(Tomcat 등)는 자신만의 규칙으로 필터를 관리하기 때문에, 스프링이 관리하는 빈(Bean) 객체들을 직접 인식할 수 없습니다. 이를 해결하기 위해 스프링은 표준 서블릿 필터를 구현한 DelegatingFilterProxy를 제공합니다. 이 대리자는 톰캣으로부터 요청을 전달받은 뒤, 실제 보안 로직을 가진 스프링 빈을 찾아 처리를 위임합니다. <br / Client - Filter - DelgatingFilterProxy(Bean Filter) - ... DelegatingFilterProxy의 또 다른 장점은 필터 빈 인스턴스 조회 시간을 지연시킬 수 있습니다. 서블릿 기반 애플리케이션 에서는 아래와 같은 초기화 순서를 가집니다. 1. 서블릿 컨테이터 시작 2. 필터 등록 및 초기화 3. Spring Context 로딩 (ContextLoaderListener) 여기서 문제가 발생하는데, 필터는 컨테이너 시작 시점에 먼저 생성 및 등록되지만 Spring Bean 은 그 이후에 생성됩니다. 즉 일반적인 방식으로는 필터에서 Spring Bean을 바로 주입 받을 수 없습니다. 이 문제를 해결하기 위해서 컨테이너에는 DelegatingFilterProxy만 미리 등록하고, 실제 필터 Bean은 Spring Context 로딩이 완료된 이후 생성되도록 구현합니다. 필터에 요청이 들어오는 시점에 Bean을 조회하여 위임하도록 설계되어 있습니다. FilterChainProxy Spring Security 내부에서는 실제 보안 필터들이 DelegatingFilterProxy에 직접 연결되는 것이 아닌 FilterChainProxy를 중심으로 관리됩니다. FilterChainProxy는 모든 서블릿 보안 기능이 시작되는 핵심 진입점입니다. 따라서 인증/인가와 강튼 보안 문제를 분석할 때는 FilterChianProxy에 디버깅 포인트를 잡는 것이 가장 좋습니다. FilterChainProxy는 단순 라우팅이 아니라 필수 보안 작업을 수행합니다. 예를 들어 SecurityContext, HttpFirewall 등이 있습니다. 일반 서블릿 필터는 URL 기반으로 동작하지만 FilterChainProxy의 경우 RequestMatcher 기반으로 다양한 요청 방법으로 매칭 가능합니다. 예를 들어 HTTP Method, Header, 파라미터, 경로 패턴이 있습니다. SecurityFilterChain SecurityFilterChain은 HTTP 요청에 대해 어떤 Spring Security 필터들을 실행할지 결정하는 기준이 됩니다. 특정 요청 조건(RequestMatcher)에 매칭되고, 그 요청에 적용할 필터 목록을 정의하는 객체라고 볼 수 있습니다. DelegatingFilterProxy → FilterChainProxy → SecurityFilterChain → Security Filters 보안 필터들은 일반적으로 Spring Bean으로 등록되지만, DelegatingFilterProxy 대신 FilterChainProxy 내부에서 관리합니다. Multiple SecurityFilterChain SecurityFilterChian은 여러개를 추가할 수 있습니다. 이때 FilterChainProxy는 어떤 SecurityFilterChain을 사용할지 결정하는 역할을 합니다. 이때 중요한 규칙은 다음과 같습니다. 조건에 매칭되는 첫 번째 SecurityFilterChain만 실행된다는 점입니다. 예를 들어 '/api/messages' 요청이 들어온 경우 먼저 SecurityFilterChain0의 '/api/\\' 패턴과 매칭되어 SecurityFilterChain0만 실행되고 이후 체인은 검사하지 않습니다. 즉, 뒤에 있는 SecurityFilterChain(n)은 매칭이 되더라도 실행되지 않습니다. 이 동작 방식 때문에 SecurityFilterChain을 구성할 때는 우순위와 패턴 설계가 매우 중요합니다. 참고 자료 $1
#Spring#Security#인증서버2026-04-15 · 8분