[Spring Security] Filter
3. 필터
Servlet Filter
- 서블릿보다 앞에 위치하여 사용자의 HTTP 요청과 응답을 가로채서 별도의 처리를 수행하는 컴포넌트
- 필터는 스프링 시큐리티의 핵심적인 동작 원리로, 주로 사용자 인증, 인가, 그리고 보안 취약점 처리와 같은 역할을 수행
필터 체인(FilterChain)
- 필터는 여러 개 존재할 수 있고, 필터 체인 형태로 연결된다.
- 필터 체인 : 여러 필터가 순차적으로 요청과 응답을 처리하는 구조
3-1. DelegatingFilterProxy
DelegatingFilterProxy
- Servlet의 Filter 인터페이스를 구현한 프록시 객체로, 스프링 빈이 아닌 서블릿 필터로서 동작한다.
- 스프링의 필터에게 인증 요청을 전달하여, 보안 처리를 수행하게 한다.
- 서블릿과 스프링 사이에서 중개자 역할을 하며, 스프링 시큐리티의 필터 체인으로 요청을 넘긴다.
- 스프링 부트의 자동 구성 기능을 통해 서블릿 컨테이너에 자동으로 등록되며, 애플리케이션으로 들어오는 모든 요청을 가로채어 필터링한다.
- 스프링 빈이 아닌 서블릿 객체로, 서블릿 컨테이너에 등록된다.
필요한 이유
- 스프링 시큐리티가 JavaEE 서블릿 명세를 기반으로 동작하지만, 서블릿 명세는 스프링 기술과의 연동 방법을 정의하지 않았다.
- 이를 해결하기 위해 DelegatingFilterProxy는 서블릿 필터와 스프링 필터 간의 연동을 지원하여 두 기술을 통합한다.
3-2. FilterChainProxy
FilterChainProxy
- DelegatingFilterProxy가 서블릿 필터로서 사용자 요청을 가로채면, 이를 FilterChainProxy에게 위임한다.
- FilterChainProxy는 스프링 컨테이너에서 관리되는 스프링 빈으로, SecurityFilterChain을 관리한다.
- FilterChainProxy는 SecurityFilterChain으로 요청을 넘기고, 이 보안 필터 체인을 통과하면서 보안 처리를 수행한다.
- SecurityFilterChain은 여러 필터로 구성되어 있으며, 요청이 순차적으로 필터를 통과하게 된다.
동작 방식
- DelegatingFilterProxy는 사용자 요청을 FilterChainProxy에게 위임한다.
- FilterChainProxy는 SecurityFilterChain을 호출하여, 각 필터가 보안과 관련된 처리를 진행한다.
- SecurityFilterChain에 있는 필터들이 통과되며, Security 관련 처리들이 진행된다.
- matches() 메서드로 요청을 처리할 SecurityFilterChain을 결정하고, getFilter()로 필터들을 적용한다.
SecurityFilterChain 인터페이스
- matches()
- 해당 요청이 SecurityFilterChain을 거쳐야 하는지 여부를 결정한다.
- RequestMatcher 인터페이스를 사용하여 요청이 일치하는지 확인한다.
- matches()가 true를 반환하면 요청은 해당 SecurityFilterChain을 거치게 된다.
- getFilter()
- getFilter() 메서드가 호출되면, 요청이 SecurityFilterChain 구현체의 필터 목록에 있는 모든 필터를 거치게 된다.
3-3. SecurityFilterChain
SecurityFilterChain
- 보안 필터 체인으로, 개별 보안 필터들이 순차적으로 요청을 처리한다.
- 각각의 필터는 HTTP/HTTPS 요청에 대한 특정 보안 처리를 수행한다.
DelegatingFilterProxy에 의해 호출되며, 요청에 따라 적절한 필터가 동작한다.
사용 방식
- 개별 보안 필터들은 스프링 빈으로 관리된다.
- DelegatingFilterProxy가 아닌 FilterChainProxy에 등록해야 한다.
- SecurityFilterChain을 스프링 빈으로 등록하고, HttpSecurity 객체를 사용하여 필터들을 등록한다
SecurityConfig.java
@Configuration
과@EnableWebSecurity
을 사용하여 보안 설정을 정의한다.filterChain 메서드는
HttpSecurity
객체를 통해 보안 필터를 설정한다.@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(Customizer.withDefaults()) // CSRF 방지용 필터 추가 .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated() ) // 인가 처리용 필터 추가 .formLogin(Customizer.withDefaults()); // Username/Password 인증 필터 추가 return http.build(); } }
3-4. SecurityFilter
Spring Security Filter instances
- 인증, 인가 및 보안 취약점에 대한 방어를 위해 스프링 시큐리티가 제공하는 다양한 필터 클래스들
- 각각 특정 보안 기능을 수행하며, 직접 구현하지 않고도 기본적인 보안 처리를 손쉽게 적용할 수 있다.
- 예시
- UsernamePasswordAuthenticationFilter: 아이디/패스워드 기반 인증 요청을 처리한다.
- BasicAuthenticationFilter: HTTP Basic 인증을 수행한다.
- 장점
- 기본적인 보안 처리를 직접 구현하지 않고도 보안 기능을 쉽게 적용할 수 있다.
- 비즈니스 로직 개발에만 집중할 수 있으며, 보안 관련 코드의 복잡성을 줄일 수 있다.
SecurityFilter 등록 방법
- SecurityFilterChain은 HttpSecurity 객체를 통해 필터를 구성하고, 이를 Bean으로 등록하여 스프링 컨테이너에서 관리되도록 한다.
filterChain(HttpSecurity http)
메서드 내부에서 애플리케이션에서 필요한 각각의 필터를 등록한다.- 필터들은 설정 파일인 SecurityConfig.java에서 관리하며, 스프링 부트가 자동으로 설정한 기본 필터 외에 필요에 따라 직접 추가할 수 있다.
Security Filter들의 동작 순서
CsrfFilter → UsernamePasswordAuthenticationFilter → BasicAuthenticationFilter → AuthorizationFilter
- CsrfFilter가 먼저 동작하여 CSRF 공격을 방지한다.
- UsernamePasswordAuthenticationFilter가 클라이언트로부터 전달받은 ID와 Password를 기반으로 사용자의 인증을 수행한다.
- BasicAuthenticationFilter가 HTTP Basic 인증 방식을 사용하여 인증을 수행한다.
- 이 필터는 다양한 인증 방식 중 하나로 설정된 경우에 동작한다
- 인증이 성공한 후, AuthorizationFilter가 요청 리소스에 따라 권한 처리를 수행한다.
- 인증은 항상 인가보다 먼저 수행되어야 한다.
우리 FISA 수업을 참고하였습니다.