Contents
1. Spring Security Filter Chain1️⃣ 전체 구조 (큰 그림)2️⃣ SecurityFilterChain이란?3️⃣ 동작 원리 (핵심 흐름)4️⃣ 반드시 알아야 할 핵심 필터들5️⃣ 인증 관련 핵심 객체 이해6️⃣ 필터 실행 순서가 중요한 이유7️⃣ 커스텀 필터 추가 시 필수 개념8️⃣ Stateless vs Stateful 차이9️⃣ 실무에서 자주 발생하는 문제🔟 실행 흐름(A) 시작 준비 단계(B) “누구냐?”를 판단하는 인증 단계(C) “없으면 익명 처리” 단계(D) 문제 발생 시 처리하는 “안내데스크”(E) 마지막 관문: “여기 들어갈 권한이 있냐?”(F) 통과하면 컨트롤러(G) 요청 끝날 때 정리1. Spring Security Filter Chain
스프링 시큐리티의 본질
서블릿 필터 기반 보안 프레임워크 컨트롤러 이전 단계에서 요청을 가로채 인증/인가를 처리
1️⃣ 전체 구조 (큰 그림)
Client Request
↓
Servlet Container Filter Chain
↓
DelegatingFilterProxy
↓
FilterChainProxy (Spring Security)
↓
Security Filter Chain (여러 보안 필터)
↓
DispatcherServlet → Controller1) DelegatingFilterProxy
- 서블릿 필터와 스프링 빈을 연결하는 브리지
- 실제 보안 처리는 스프링 빈에게 위임
2) FilterChainProxy (핵심)
- 스프링 시큐리티의 중앙 허브
- 여러 개의 SecurityFilterChain 중 매칭되는 체인 선택
- 내부적으로 보안 필터들을 순서대로 실행
2️⃣ SecurityFilterChain이란?
특정 요청 패턴에 적용되는 필터 묶음.
@Bean
SecurityFilterChain filterChain(HttpSecurity http) { ... }✔ 요청 URL 기준으로 체인 선택 가능
예:
/api/** → JWT 인증 체인
/admin/** → 폼 로그인 체인3️⃣ 동작 원리 (핵심 흐름)
1) 요청 진입
- FilterChainProxy가 요청과 매칭되는 체인 선택
2) 인증 필터 실행
- 인증 정보 추출 (세션 / JWT / Basic Auth 등)
3) SecurityContext 생성
- 인증 성공 시 SecurityContextHolder 저장
4) 인가 검사
- 접근 권한 확인
5) 컨트롤러 진입
4️⃣ 반드시 알아야 할 핵심 필터들
실제 필터는 많지만, 실무 핵심만 정리.
1) SecurityContextPersistenceFilter
- 역할
- 요청 시작 시 SecurityContext 로드
- 요청 종료 시 저장
- 중요 포인트
- 세션 기반 인증의 핵심
2) UsernamePasswordAuthenticationFilter
- 역할
- 폼 로그인 처리
- ID/PW → Authentication 객체 생성
- 동작
Request → UsernamePasswordAuthenticationToken
→ AuthenticationManager
→ 인증 성공/실패3) BasicAuthenticationFilter
- 역할
- HTTP Basic 인증 처리
- 특징
- Authorization 헤더 사용
4) BearerTokenAuthenticationFilter (JWT 환경)
- 역할
- Authorization: Bearer {token} 처리
- 핵심
- Stateless 인증의 핵심 필터
5) AnonymousAuthenticationFilter
- 역할
- 인증 정보 없을 때 익명 사용자 생성
- 왜 필요?
- null 대신 익명 객체 사용 → NPE 방지
6) ExceptionTranslationFilter
- 역할
- 인증/인가 예외 처리
- 담당 예외
- AuthenticationException → 로그인 유도
- AccessDeniedException → 403 반환
7) FilterSecurityInterceptor ⭐ (인가의 핵심)
- 역할
- 최종 접근 권한 검사
- 내부 처리
권한 체크 → AccessDecisionManager 호출
- 가장 중요한 필터 중 하나
5️⃣ 인증 관련 핵심 객체 이해
1) Authentication
- 의미
- 인증 상태 + 사용자 정보
- 주요 구현체
- UsernamePasswordAuthenticationToken
- JwtAuthenticationToken 등
2) AuthenticationManager
- 역할
- 인증 처리 총괄
- 실제 위임 대상
- AuthenticationProvider
3) AuthenticationProvider
- 역할
- 실제 인증 로직 수행
- 예
- DB 사용자 검증
- JWT 검증
4) SecurityContextHolder ⭐
- 역할
- 현재 사용자 인증 정보 저장소
- 중요 개념
- ThreadLocal 기반
SecurityContextHolder.getContext().getAuthentication()
6️⃣ 필터 실행 순서가 중요한 이유
스프링 시큐리티는 순서 의존적 구조
1) 예
- 인증 필터 → 인가 필터 순서 필수
- 예외 필터는 인가 필터 앞에 위치
2) 순서가 잘못되면
- 인증이 안 됨
- 권한 체크 실패
- 예외 처리 불능
7️⃣ 커스텀 필터 추가 시 필수 개념
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
- 언제 사용?
- JWT 인증
- API Key 인증
- 로깅 / 트래킹
- 핵심 전략
방식 | 의미 |
addFilterBefore | 특정 필터 이전 |
addFilterAfter | 특정 필터 이후 |
addFilterAt | 교체 |
8️⃣ Stateless vs Stateful 차이
구분 | Stateful (세션) | Stateless (JWT) |
인증 저장 | 세션 | 토큰 |
서버 상태 | 유지 | 없음 |
필터 핵심 | SecurityContextPersistenceFilter | BearerTokenAuthenticationFilter |
확장성 | 낮음 | 높음 |
9️⃣ 실무에서 자주 발생하는 문제
1) 인증은 됐는데 SecurityContext가 비어 있음 🚨
- 원인
- 필터 순서 문제
- context 저장 누락
2) JWT 필터가 동작 안 함 🚨
- 원인
- 체인 매칭 실패
- addFilter 위치 오류
3) permitAll인데 인증 필터는 실행됨 🚨
- 정상 동작임
- 필터 체인 ≠ 인가 설정
🔟 실행 흐름
(A) 시작 준비 단계
1) SecurityContextPersistenceFilter
- 요청이 들어오면 “이전 로그인 정보”를 꺼내서 준비
- 세션 기반 : 세션에서 인증정보 로드
- JWT 같은 Stateless : 보통 비어있을 수 있음(대신 뒤에서 토큰으로 채움)
➡️ 비유 : 출입기록부 열어보기
(B) “누구냐?”를 판단하는 인증 단계
- 여기서부터는 프로젝트에 따라 다르게 동작
2) (선택) BearerTokenAuthenticationFilter (JWT일 때)
- 요청 헤더에서
Authorization: Bearer 토큰을 찾음
- 토큰 검증이 성공하면 “이 사용자는 누구다”를 확정하고 저장
➡️ 비유 : 모바일 탑승권(QR) 스캔
3) (선택) UsernamePasswordAuthenticationFilter (폼로그인일 때)
- 로그인 요청(
/login)이 들어오면
- id/pw를 꺼내서 인증 처리
- 성공하면 “이 사용자”로 확정하고 저장
➡️ 비유 : 직원에게 신분증+비밀번호로 확인받기
4) (선택) BasicAuthenticationFilter (Basic Auth일 때)
- Authorization 헤더에서 Basic 인증 처리
➡️ 비유 : 간단 출입증(아이디/패스워드) 검사
(C) “없으면 익명 처리” 단계
5) AnonymousAuthenticationFilter
- 위 단계까지 와도 “사용자 확정”이 안 됐으면
- “익명 사용자”라는 표식을 만들어 넣음
중요 : 익명은 “로그인 상태”가 아니지만, 시큐리티는 null 대신 익명을 넣고 통일된 방식으로 처리함.
➡️ 비유: 방문객 스티커 붙여줌
(D) 문제 발생 시 처리하는 “안내데스크”
6) ExceptionTranslationFilter
- 뒤에서 권한 검사하다가 문제가 생기면
- 로그인 안 했으면 → 로그인 화면/401 처리
- 권한 없으면 → 403 처리
- “예외를 사용자에게 보여줄 결과”로 바꾸는 역할
➡️ 비유: 규정 위반 시 안내데스크로 보내기
(E) 마지막 관문: “여기 들어갈 권한이 있냐?”
7) FilterSecurityInterceptor ⭐ (인가 핵심)
- 최종적으로 이 요청 URL/메서드가 요구하는 권한을 확인
- 예:
/admin/**는 ADMIN 권한 필요/api/**는 로그인 필요- 어떤 건
permitAll()로 모두 허용
➡️ 비유 : 목적지 게이트 입장권 검사(마지막 관문)
(F) 통과하면 컨트롤러
여기까지 통과하면
- DispatcherServlet → Controller로 이동
(G) 요청 끝날 때 정리
다시 SecurityContextPersistenceFilter (요청 종료 시점)
- 요청 처리 끝나면 SecurityContext를 정리
- 세션 기반이면 저장
- ThreadLocal도 청소
➡️ 비유: 출입 기록 마감/정리
Share article