티스토리 뷰
스프링 시큐리티에 대해 전무한 상태였다.
스프링 시큐리티를 이용하면 사용자의 인증, 인가 그리고 보안 처리를 할 수 있다. 그 과정에서 필터는 가장 중요한 핵심이라는 것을 알게 되었지만 그만큼 어렵게 느껴졌기 때문에 필터에 대해 천천히 알아보려고 한다.
Filter와 FilterChain
Filter
클라이언트의 요청과 응답에 대해 전처리, 후처리를 수행하는 컴포넌트로 서블릿 앞 단에 위치해서 클라이언트의 요청-응답을 가로채서 인증, 인가, 로깅, 보안 등의 작업을 처리한다.
필터는 서블릿 컨테이너의 컴포넌트로 서블릿 컨테이너에 의해 관리된다. 이때 필터는 서블릿 컨테이너의 필터일 수도 있고, 스프링에서 제공하는 필터일 수도 있고, 개발자가 만든 필터일 수도 있다. 즉, 필터는 서블릿 컨테이너 내에서 관리되지만, 스프링 환경에서도 활용될 수 있는 중요한 요소이다.
Filter 인터페이스를 보면 javax.servlet 패키지 내에 존재하는데, 이는 서블릿 컨테이너에 의해서 관리된다는 것이다.
package javax.servlet;
import java.io.IOException;
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
default void destroy() {
}
}
init() 서블릿 컨테이너가 필터를 등록하는 초기화 과정에서 호출된다.
doFilter() 필터의 실질적인 작업을 수행하는 메서드로서 요청과 응답, 그리고 필터체인 객체에 접근할 수 있다.
destroy() 서블릿 컨테이너가 필터를 제거할 때 호출된다.
FilterChain
서블릿 컨테이너에서 제공하는 컴포넌트로, 필터들이 순차적으로 처리할 요청-응답의 흐름을 관리하는 역할을 한다.
FilterChain 인터페이스를 보면 javax.servlet 패키지 내에 존재하는데, 이는 서블릿 컨테이너에 의해서 관리된다는 것이다.
package javax.servlet;
import java.io.IOException;
public interface FilterChain {
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}
doFilter() 같은 체인 상에 있는 다음 필터를 호출한다는 의미이다.
Filter 인터페이스의 doFilter는 FilterChain 객체를 매개변수로 받는데, 자신의 작업이 완료되면 FilterChain의 doFilter 메서드를 호출해서 요청이 다음 필터를 통과하게 만든다.
클라이언트 요청부터 필터가 실행되는 과정 (1)

1. 클라이언트가 HTTP 요청을 애플리케이션으로 보낸다.
2. 서블릿 컨테이너는 요청 URI 경로를 기준으로 해당 요청을 처리할 필터와 서블릿을 결정하고, 서블릿 컨테이너에 이를 포함하는 필터체인을 생성한다.
3. 각 필터는 필터 체인을 통해 순차적으로 실행된다. 각 요청을 처리한 후에 다음 필터로 요청을 전달하거나 응답을 처리한다.
4. 마지막 필터가 끝나면 서블릿이 호출되어 실제 요청을 처리하고 응답을 반환한다.
필터 순서의 중요성
필터가 처리하는 대상은 다운스트림 필터와 서블릿이다. 즉, 각 필터는 요청을 처리한 후 요청을 다음 필터로 전달하거나 서블릿이 요청을 처리할 수 있게 한다. 이 흐름에서 필터의 실행 순서는 매우 중요하다.
1. 보안상의 이유
인증 필터가 먼저 실행되지 않으면 인증되지 않은 사용자는 민감한 자원에 접근할 수 있게된다. 이 문제를 방지하려면 인증 필터가 먼저 실행되고, 다른 필터나 서블릿이 실행될 수 있도록 해야한다.
2. 성능 최적화
로깅, 캐싱, 압축과 같은 작업을 처리하는 필터들이 있다면, 인증이나 권한 검사 필터가 실행된 이후에 실행되도록 해야 불필요한 처리나 성능 저하를 방지할 수 있다. 예를 들어, 인증되지 않는 사용자는 로깅이나 데이터 캐싱을 건너뛰도록 설정할 수 있다.
따라서 필터의 역할과 우선순위를 고려하여 순서를 정확하게 설정하는 것이 매우 중요하다.
DelegatingFilterProxy, FilterChainProxy, SecurityFilterChain
위에서 필터는 서블릿 컨테이너의 필터일 수도 있고, 스프링의 필터일 수도 있다고 했다.
또한 필터와 필터체인은 서블릿 컨테이너에서 관리되는 컴포넌트로, 클라이언트로부터 요청이 들어오면 서블릿 컨테이너는 필터와 서블릿을 포함하는 필터체인을 생성한다고 했다.
서블릿 컨테이너와 스프링 컨테이너는 서로 독립적이며, 서로간에 직접적인 연관을 맺지 않는다. 그렇다면 서블릿 컨테이너가 필터체인을 생성할 때, 어떻게 스프링 컨테이너에 정의된 필터를 참조할 수 있는 것일까.
바로 DelegatingFilterProxy 덕분이다. 그럼 한번 알아보자.
DelegatingFilterProxy
Filter의 구현체로써, 스프링에서 관리되는 필터를 서블릿 컨테이너의 필터 체인에 연결하기 위한 프록시 역할을 한다. 이 프록시도 서블릿 컨테이너에 등록되고 서블릿 컨테이너가 생명주기를 관리한다.
DelegatingFilter 자체는 필터로서 동작하지 않고, 스프링 컨테이너에 정의된 Filter의 구현체인 빈(Bean)을 찾아서 해당 필터(Bean)로 요청을 위임한다. 이 스프링 빈(Bean)은 DelegatingFilterProxy 내에서 대리인 역할을 하는 delegate로 설정된다. 즉, DelegatingFilterProxy는 서블릿 필터로서 요청을 가로챈 후, delegate로 설정된 스프링 빈(Bean)에 요청을 넘겨서 처리하도록 한다.
FilterChainProxy
DelegatingFilterProxy 내에서 대리인 역할을 하는 Filter의 구현체인 특별 빈(Bean) 필터로, 스프링 컨테이너에서 관리되지만 서블릿 컨테이너에서 실행되도록 설정된다. 스프링 빈(Bean)이기 때문에, 서블릿 컨테이너에서 필터로 등록될 때 DelegatingFilterProxy로 감싸져서 서블릿 컨테이너와 스프링 컨테이너를 연결하는 방식으로 사용된다.
즉, DelegatingFilterProxy 필터가 가로챈 요청을 FilterChainProxy에게 위임하면, FilterChainProxy는 자신이 관리하는 필터체인에 요청을 흘려보낸다.
SecurityFilterChain
FilterChainProxy에서 사용되는 필터체인으로, 현재 요청에 대해 호출되어야 하는 Spring Security Filter 인스턴스들을 갖는다. Spring Security Filter들을 체인 형태로 구성하여, 각 필터를 순차적으로 실행한다. 이 필터체인에 구성되어 있는 필터들은 스프링 컨테이너에 등록되어 있는 빈(Bean)이다.
필터의 흐름

1. 클라이언트의 요청이 들어오면, 서블릿 컨테이너는 필터체인에 따라 DelegatingFilterProxy를 실행한다.
서블릿 컨테이너에 구성된 필터체인은 여러개의 필터로 구성되어 있으며, DelegatingFilterProxy는 그 중 하나인 필터이다.
2. DelegatingFilterProxy는 자신이 참조하는 대리인 FilterChainProxy에게 요청을 위임한다.
3. FilterChainProxy는 여러 개의 SecurityFilterChain 중에서 요청에 맞는 것을 선택하여, 해당 체인에 정의된 필터들을 순차적으로 실행한다.
4. SecurityFilterChain 의 필터들이 요청에 대한 처리를 완료한 후, 그 뒤에 서블릿 컨테이너에 등록된 다른 필터들이 차례대로 실행되고 서블릿이 호출된다. 만약 DelegatingFilterProxy 이후 필터가 없으면 바로 서블릿을 호출한다.
스프링 시큐리티의 첫 부분을 알아가는데도 정말 어려웠다.
다음에는 인증시 시큐리티가 어떻게 진행되는지에 알아봐야겠다.
시큐리티 2탄으로 돌아와야겠다.
참고
https://docs.spring.io/spring-security/reference/servlet/architecture.html
Architecture :: Spring Security
The Security Filters are inserted into the FilterChainProxy with the SecurityFilterChain API. Those filters can be used for a number of different purposes, like authentication, authorization, exploit protection, and more. The filters are executed in a spec
docs.spring.io
'Framework > Spring' 카테고리의 다른 글
Spring Security 의 두 번째: 인증 (0) | 2024.11.18 |
---|---|
auto-configuration에 대하여 (0) | 2024.10.23 |
[Web] Servlet 과 Servlet Container (0) | 2022.12.26 |
[Spring] DispatcherServelt (Feat. Front Controller) (0) | 2022.12.16 |
[Spring] 순환 참조 (0) | 2022.12.13 |
- Total
- Today
- Yesterday
- Security
- object
- AutoConfiguration
- 오블완
- JPA
- 인스턴스변수
- Caching
- spring boot
- 로드 밸런서
- HashSet
- Spring
- fail-safe
- nosql
- Red-Black Tree
- Load Balancer
- 추상클래스
- nginx
- 고정 세션
- 다중화
- 인터페이스
- 자동구성
- HashMap
- java
- Sticky Session
- 티스토리챌린지
- fail-fast
- 정적변수
- @conditional
- syncronized
- Hash
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |