본문 바로가기

멋쟁이사자처럼_부트캠프/개념STUDY

Spring Security Filter Chain

Spring Security : 웹 애플리케이션에 보안 기능을 쉽게 붙일 수 있도록 해주는 프레임워크

  • 제공하는 기능:
    • 로그인/로그아웃
    • 권한(Role) 기반 접근 제어
    • CSRF 방지
    • 세션 관리
    • 비밀번호 암호화
    • JWT 인증 등

1. Security Filter Chain이란? – 요청을 지키는 보안 게이트

Spring Security는 요청이 컨트롤러에 도달하기 전, 여러 보안 필터들을 차례대로 통과시키면서
“이 요청이 안전한가?”, “누구인가?”, “권한이 있는가?”를 체크하는 시스템입니다.

(HTTP 요청을 필터로 감싸 처리함)

주요 구조:

  • DelegatingFilterProxy : Spring Security 필터로 진입하는 입구
    • 톰캣(또는 서블릿 컨테이너)에 등록된 서블릿 필터
    • 진짜 필터 로직은 Spring 안에 있음
  • FilterChainProxy : 등록된 모든 SecurityFilterChain을 관리
    • 들어온 요청 URL에 따라 어떤 SecurityFilterChain을 적용할지 결정함
  • SecurityFilterChain : 각 요청 패턴에 대해 어떤 필터들을 적용할지 정의
    • 실제 필터들 (JWT 검사, 로그인 검사 등)을 정의한 집합, FilterChainProxy가 관리함

→ 이 체인을 통해 보안 로직이 동작합니다.

 

2. 주요 필터들

필터들의 순서와 역할:

필터 이름 하는 일
SecurityContextPersistenceFilter 요청 시작 시 SecurityContext를 꺼내고, 응답 시 저장
UsernamePasswordAuthenticationFilter 로그인 요청 (/login)에서 ID/PW 인증 수행
JwtAuthenticationFilter (커스텀) Authorization 헤더에서 JWT 토큰 파싱 인증 처리
ExceptionTranslationFilter 인증 or 인가 실패 시 예외 처리 (401, 403)
FilterSecurityInterceptor 최종 권한 체크 (@PreAuthorize, hasRole() 등과 연결됨)

 

이 필터들은 순서대로 실행되고, 중간에 실패하면 요청이 막히거나 예외가 터집니다.

 

3. 실제 요청 흐름 시나리오

예시: 로그인이 필요한 페이지에 접근할 때

[클라이언트] → GET /mypage
↓
1. SecurityContextPersistenceFilter (이전에 로그인한 사용자인가?)
↓
2. JwtAuthenticationFilter (토큰이 있나? 유효한가?)
↓
3. ExceptionTranslationFilter (에러 나면 401/403 응답)
↓
4. FilterSecurityInterceptor (접근 권한 있는가?)
↓
[컨트롤러] → @GetMapping("/mypage")

→ 이 흐름 속에서 인증/인가/예외가 전부 필터에서 이뤄짐

 

 

4. 커스텀 필터

우리가 직접 만든 JWT 필터 추가할 땐?

http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

❗ 위치 잘못 잡으면 인증이 안 되거나, 필터가 무시됨

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtFilter;

    public SecurityConfig(JwtAuthenticationFilter jwtFilter) {
        this.jwtFilter = jwtFilter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests()
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); // ✅

        return http.build();
    }
}

 

5. 실전 디버깅 팁 – 실제로 어떻게 확인하나

필터 순서 확인: FilterChainProxy에서 로그 찍기

Filter[] filters = filterChainProxy.getFilters("/mypage");
Arrays.stream(filters).forEach(System.out::println);

 

인증된 유저 확인:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
System.out.println(auth.getName()); // 현재 로그인한 사용자 ID

 

6. 마무리 요약

  • Spring Security는 요청을 필터 체인으로 감싸서 보안 로직을 처리
  • 필터 순서와 역할을 정확히 이해해야 디버깅과 커스터마이징이 쉬움
  • 커스텀 필터는 어디에 넣느냐가 정말 중요
  • 실무에선 JWT 필터, Exception 처리 필터, 인가 필터가 핵심

'멋쟁이사자처럼_부트캠프 > 개념STUDY' 카테고리의 다른 글

Spring에서의 API 예외 처리 전략  (0) 2025.07.20
TDD와 테스트 전략  (0) 2025.06.22
OAuth2  (0) 2025.06.03
JWT  (0) 2025.05.20
기본 웹 아키텍처 개념  (0) 2025.05.13