SecurityFilterChain

2025. 12. 16. 09:35Spring Security

🔗 SecurityFilterChain

SecurityFilterChain은 Spring Security에서 실제 보안 정책과 로직이 적용되는 최소 단위의 묶음입니다. 이는 여러 개의 Spring Security 필터들을 특정한 순서로 엮어 놓은 체인(Chain) 그 자체입니다.

SecurityFilterChain은 웹 애플리케이션의 특정 Path 패턴에 대해 어떤 보안 필터들이, 어떤 순서로 실행되어야 하는지를 정의합니다.

1. SecurityFilterChain의 구성 요소

SecurityFilterChain은 본질적으로 다음 두 가지 주요 구성 요소로 이루어집니다.

 

A. RequestMatcher (요청 매칭 조건)

  • 역할: 해당 필터 체인이 어떤 HTTP 요청에 적용될지 결정합니다. URL 경로, HTTP 메서드, 헤더 등 다양한 조건을 기반으로 요청을 필터링합니다.
  • 예시: http.securityMatcher("/admin/**") 와 같이 설정되어, /admin/으로 시작하는 모든 요청에 대해서만 이 체인을 적용합니다.

B. 필터 리스트 (List<Filter>)

  • 역할: 실제로 보안 작업을 수행하는 일련의 Spring Security 전용 필터들입니다. 이 필터들은 특정 순서를 가지고 요청을 처리하며, 이 순서는 Spring Security 내부에서 엄격하게 관리됩니다.
  • 예시: UsernamePasswordAuthenticationFilter, ExceptionTranslationFilter, FilterSecurityInterceptor 등.

2. SecurityFilterChain의 내부 필터 목록과 순서

하나의 SecurityFilterChain에는 디폴트로 10~20개에 달하는 필터들이 포함될 수 있으며, 이 필터들은 미리 정의된 순서로 실행됩니다. 이 순서는 FilterOrderRegistration에 의해 결정되며, 개발자가 필터의 순서를 임의로 바꾸는 것은 권장되지 않습니다.

순서 범위 주요 필터 (일부 예시) 역할
전처리/세션 SecurityContextPersistenceFilter 요청 시작 시 SecurityContextHolderSecurityContext를 로드하고, 요청 완료 시 저장/제거합니다. (인증 정보 유지)
  SessionManagementFilter 세션 관리(동시 세션 제어, 세션 만료 등)를 처리합니다.
Authentication UsernamePasswordAuthenticationFilter Form 기반 로그인 요청(/login)을 가로채 사용자 인증을 시도합니다.
  BasicAuthenticationFilter HTTP Basic 인증 헤더를 처리합니다.
  JwtAuthenticationFilter (개발자가 커스텀으로 추가) JWT 토큰을 검증하여 인증 정보를 설정합니다.
Authorization ExceptionTranslationFilter 인증 또는 권한 부여 과정에서 발생하는 예외(Ex.)를 처리합니다. (AuthenticationException → 로그인 페이지, AccessDeniedException → 접근 거부 페이지)
  FilterSecurityInterceptor 필터 체인의 가장 마지막에 위치하며, 최종적으로 리소스에 대한 접근 권한(인가)을 확인합니다.

 

3. SecurityFilterChain의 설정 및 생성

Spring Boot 2.7 이상에서는 SecurityFilterChain@Bean으로 등록하여 사용자가 원하는 보안 설정을 구성합니다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    // 첫 번째 체인: '/api/**' 경로는 토큰 인증으로 Stateless하게 처리
    @Bean
    public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/api/**") // 이 체인을 적용할 요청 경로
            .csrf(csrf -> csrf.disable()) // API는 보통 CSRF 비활성화
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            // .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            ;
        return http.build();
    }

    // 두 번째 체인: 다른 모든 경로 ('/**')는 폼 로그인으로 처리
    @Bean
    public SecurityFilterChain webFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults()); // 폼 로그인 활성화

        return http.build();
    }
}

 

4. FilterChainProxy와의 관계 (다중 체인)

  • FilterChainProxy는 개발자가 @Bean으로 등록한 모든 SecurityFilterChain 객체들을 내부 리스트로 가집니다.
  • 요청이 들어오면, FilterChainProxy는 이 리스트를 순서대로 검사합니다.
  • 가장 먼저 요청의 RequestMatcher와 일치하는 첫 번째 SecurityFilterChain만 실행하고 나머지 체인은 무시합니다.
  • 이 순서 때문에, 더 구체적인 규칙(예: /api/)을 가진 체인을 덜 구체적인 규칙(예:/)을 가진 체인보다 먼저 등록해야 합니다. (Spring Security는 기본적으로 등록된 @Bean 순서를 따릅니다.)

SecurityFilterChain은 Spring Security가 제공하는 다양한 보안 기능을 통합하고, 애플리케이션의 요구사항에 맞게 보안 정책을 모듈화하여 관리할 수 있게 해주는 핵심 개념입니다.