스프링 시큐리티 6 기준!
실제 스프링 시큐리티를 만지면서 너무 어렵고 깊이있게 파고들고 싶어서 좀 더 알아보는 흐름을 갖고 싶어서 써보겠다
실제 유저가 스프링에 요청을 보내는 순간으로 부터 시작해서 스프링 시큐리티 작동 원리를 찾아보고
일반적인 form 로그인과 Oauth의 경우까지 알아보자
1. http 요청 시 흐름
Client가 API 요청을 하면
Web Application server(Java에서는 Tomcat) → Servlet(Java에서는 Dispatcher Servlet ) → Controller
순서로 요청이 전달되는데,
그 중 Filter chain은 Web Application server와 Servlet 사이에서 작동한다.
// 흐름
HTTP 요청 → WAS → 필터 → 서블릿 → 컨트롤러
// 체인
HTTP 요청 → WAS → 필터 → 필터2 → 필터3 → 서블릿 → 컨트롤러
(톰캣과 Dispatcher Servlet사이에 존재하는 필터체인)
2. FilterChain
필터는 여러 개가 체인처럼 연결돼 있어서, 요청이 하나씩 통과하면서 점검받는 구조(순서대로가 중요)
각 필터는 doFilter 메서드를 통해 요청을 받아서 뭔가를 하고, 다음 필터나 서블릿으로 넘김.
(그래서 모든 필터를 호출 후 doFilter을 메서드를 호출해 넘겼어야 했다)
3. 스프링 시큐리티 실제 흐름

흐름도
로깅 필터 -> 인코딩 필터 -> DelegatingFilterProxy -> 커스텀 필터
쉽게 말하면, DelegatingFilterProxy는 호출만 하고,
실제 보안 로직은 FilterChainProxy가 여러 필터를 불러서 처리!!
적절한 인증/인가 작업 후 다시 커스텀필터를 호출 후 최종 Dispatcher Servlet로 mvc 동작!
4. 스프링 시큐리티 필터 종류들(FilterChainProxy)

FilterChainProxy는
위 종류들을 갖고 있는 springSecurityFilter들을 요청에 맞게 호출함
일반 세션 폼 로그인 기반 시 springSecurityFilter 중요한 필터 흐름
SecurityContextPersistenceFilter
- 이전 요청에서 저장된 SecurityContext 복원(세션에서 인증 정보 가져오기) or
- SecurityContextHolder의 생애 주기를 관리(실제 인증빼고)
- 호출 후 응답까지의 로컬쓰레드에 해제까지의 전반적인 흐름의 시작과 끝에 있음
try- context 저장, finally- 쓰레드로컬에서 해제
-세션 기반이라, jwt 쓸꺼면 상관없다.
security 5.7 이후로 @deprecated됨
여기에 대해서도 조금 쓸 일이 많은 것 같긴 하다..
무조건 세션에 저장을 안해도 된다는 뜻인 거 같음
UsernamePasswordAuthenticationFilter ( 실제 핵심 로그인처리)
- 로그인 폼에서 아이디/비밀번호를 받아 인증 처리
- authenticaiton에 실제로 인증을 요청하는 핵심
AuthenticationManager, AuthenticationProvider
BasicAuthenticationFilter
- HTTP Basic 인증(헤더에 인증 정보 넣는 방식) 처리.
AnonymousAuthenticationFilter
- 로그인 안 한 사용자를 "익명 사용자"로 설정.
ExceptionTranslationFilter
- 보안 예외(401, 403 등) 처리.
FilterSecurityInterceptor
- 최종 권한 체크.
@EnableWebSecurity(debug = true)

5. OAuth 의 경우
OAuth2AuthorizationRequestRedirectFilter
특정 uri에서 호출됨 :/oauth2/authorization/{provider}
ex) 구글의 예시:
/oauth2/authorization/google
OAuth2 로그인 요청을 받아 사용자를 외부 제공자의 로그인 페이지로 리다이렉트시키는 필터.
순서도
1. 로그인 요청 시 인증 요청(Authorization Request)을 만듦
2 .Authorization Request에는 (client_id,redirect_id, 스코프 등)이 포함
3. 사용자를 제공자의 로그인 페이지로 리다이렉트 (예: 구글 로그인 화면).
결과 !
사용자가 구글 같은 제공자에서 로그인하면 인가 코드(authorization code)가 리다이렉트 URI로 돌아온다. 이 코드는 다음 필터가 처리!
OAuth2LoginAuthenticationFilter
위에서 받은 인가 코드를 처리해 사용자 인증을 완료하고 SecurityContextHolder에 인증 정보를 설정하는 필터
특정 uri에서 호출됨 /login/oauth2/code/*
ex) 구글의 예시: /login/oauth2/code/google
(내가 지정한 redirectURL)
1. 위 코드에서 받아온 인증코드로 구글에게 제공자 정보에 접근 가능한 액세스 토큰 발행
2. 액세스 토큰으로 사용자 실제 정보 받음
OAuth2UserCustomService가 이 데이터를 처리 (예: DB 저장).
블로그 만들기 -Oauth2구글에 요청이 자동으로 간다고?
(실제 실행 메서드가 궁금하면 보고오자)
3. OAuth2AuthenticationToken을 만들어 SecurityContextHolder에 저장.
4.성공 시 oAuth2SuccessHandler() 호출, 실패 시 oAuth2failureHandler() 호출
결과 !
인증 성공 시 SecurityContextHolder에 사용자 정보가 채워지고, 내 핸들러가 JWT를 발급해 클라이언트에 준다. 이후 요청은 TokenAuthenticationFilter가 JWT로 인증 유지!
usernamePasswordauthenticationfilter의 인증 과정을 거침

필터들은 OAuth 2.0 로그인 기능을 지원하기 위해 별도로 추가된 필터라서
"spring-security-oauth2-client" 의존성 추가가 필수다.
OAuth의 흐름도
-
요청 → DelegatingFilterProxy → FilterChainProxy.
-
OAuth2AuthorizationRequestRedirectFilter 후 OAuth2LoginAuthenticationFilter로 인증 처리.
-
SecurityContext에 인증 정보 저장 → 디스패처 서블릿.
-- 질문 -- 미완
HttpSessionOAuth2AuthorizationRequestRepository가 필요한 이유를 따라가다

-
서버는 그 클라이언트의 요청을 끝내고 스레드를 해제해.
-
다른 클라이언트의 요청(예: 다른 사용자의 페이지 조회, API 호출)을 계속 처리해.
-
콜백 요청이 오면 새로운 스레드로 처리 시작.
-
효율성: 서버는 리다이렉트를 보낸 후 리소스를 해제하고 다른 요청을 처리해. 콜백 요청이 올 때만 다시 처리하면 되니까 확장성이 좋아.
-
보안: 인가 요청을 세션이나 쿠키에 저장하고, state 파라미터로 CSRF 공격을 방지해. 기다리는 방식은 상태를 유지하기 어렵거나 새로운 보안 위험이 생길 수 있어.
-
사용자 경험: 사용자는 익숙한 제공자 UI(구글 로그인 화면)에서 인증하고, 애플리케이션으로 자연스럽게 돌아와. 기다리는 방식은 사용자에게 "로딩 중" 같은 부자연스러운 UI를 보여줄 가능성이 커.
-
표준화: OAuth 2.0은 전 세계적으로 표준화된 프로토콜이라, 구글, 페이스북, 깃허브 등 모든 제공자가 리다이렉트 기반으로 동작해. 기다리는 방식은 표준에서 벗어나서 호환성 문제 생김.
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 exploit protection,authentication, authorization, and more. The filters are executed in a speci
docs.spring.io
https://velog.io/@zini9188/Spring-Security-Filter%EC%99%80-FilterChain
[Spring Security] Filter와 FilterChain
서블릿 필터는 서블릿 기반 애플리케이션의 엔드포인트에 요청이 도달하기 전에 중간에 요청을 가로챈 후 어떤 처리를 할 수 있도록 해주는 JAVA의 컴포넌트필터의 처리가 완료되면 디스패처서
velog.io
https://www.baeldung.com/spring-mvc-handlerinterceptor-vs-filter
'Spring' 카테고리의 다른 글
JPA 1+N 문제 실습 (0) | 2025.04.12 |
---|---|
@transactional을 private메서드에 사용하고 싶다 (0) | 2024.01.21 |
@entity 빨간줄 (0) | 2024.01.16 |