Back-end/Spring

[Spring] Spring Security 기본 구조와 인증 처리 흐름 (Filter Chain)

랑 이 2026. 1. 9. 18:23
반응형

Spring Security란?

Spring Security는 Spring 기반 애플리케이션 인증(Authentication)과 인가(Authorization)를 담당하는 보안 프레임워크

웹 애플리케이션에서 사용자의 접근을 제어하며 권한에 따른 리소스 보호하는 역할을 합니다

 

또한 Spring Security는 다양한 보안 관련 옵션을 기본으로 제공하고 있으며

대표적으로 CSRF 공격, 세션 고정(Session Fixation) 공격과 같은 웹 보안 위협을 방어할 수 있도록 지원합니다

 

여기에 JWT 기반 인증을 도입하고 Token을 HttpOnly 쿠키로 관리하는 방식으로 구현한다면 프론트에서 자바스크립트를 통한 토큰 접근을 차단할 수 있어 XSS 공격에 대한 방어 수준을 강화할 수 있습니다

 

CSRF 공격

사용자가 의도하지 않은 요청을 공격자가 대신 실행하게 만드는 공격

 

세션 고정(Session Fixation) 공격

세션 ID를 통해 사용자의 인증 정보를 탈취하는 공격

 

XSS (Cross-Site Scripting)

악성 스크립트를 웹 페이지에 사입하여 사용자의 브라우저에서 실행되도록 하는 공격

인증(Authentication)과 인가(Authorization)

Spring Security의 핵심 개념은 인증과 인가입니다 

 

인증(Authentication)

사용자가 누구인지 확인하는 과정

 

- 아이디 / 비밀번호 확인을 통해 사용자 식별

- JWT 토큰을 통한 검증

- 소셜 로그인(OAuth)를 통한 사용자 확인

 

인가(Authorization)

인증된 사용자가 어떤 자원에 접근할 수 있는지 권한을 확인하는 과정

 

- 관리자 / 일반 사용자 구분하여 특정 사용자만 접근하도록 구현                                                                                               

- 설정을 통해 특정 API 접근 제한

Spring Security 기본 구조 (Filter Chain)

Spring Security는 Filter Chain 기반 구조로 동작한다

모든 HTTP 요청은 Controller에 도달하기 전에 SecurityFilterChain을 먼저 통과하며 각 필터에서 인증, 인가가 처리된다

 

아래 다이어그램은 Spring Security의 전반적인 구조와 각 컴포넌트가 어떤 역할을 수행하는지 나타내고 있다

- 모든 요청은 SecurityFilterChain을 통과한다

- 필터 체인 내부에서 인증(Authentication), 인가(Authorization), 예외 처리를 담당한다

- 인증 결과SecurityContext에 저장되며 인가AccessDecisionManager를 통해 결정된다

SecurityFilterChain 필터 동작 순서 & 설명

다이어그램 왼쪽 파란 영역을 기준으로 요청이 위 → 아래로 통과하는 순서를 나타낸다
필터명 역할
SecurityContextPersistenceFilter SecurityContextRepository에서  SecurityContext를
로드하거나 요청 종료 시 저장하는 필터
LogoutFilter 로그아웃 요청을 감지하여 세션 무효화,쿠키 삭제
SecurityContext 초기화 등을 수행하여 해당 사용자를 로그아웃 처리
UsernamePasswordAuthenticationFilter 로그인 요청에서 ID/PW를 추출하여 AuthenticationManager로
인증을 위임하고 인증 성공 시 AuthenticationSuccessHandler를
실패 시 AuthenticationFailureHandler를 실행하는 필터이다.
DefaultLoginPageGeneratingFilter 로그인 페이지를 만들지 않았을때 기본 로그인/로그아웃 페이지를
설정하는 필터
BasicAuthenticationFilter Authorization: Basic ... 헤더를 파싱해 사용자 인증을 시도하고
성공하면 SecurityContext에 인증 정보를 세팅하는 필터
RememberMeAuthenticationFilter Remember-me 쿠키가 있으면 자동 로그인 처리를 시도해 인증을
복원하고 SecurityContext에 반영하는 필터
SecurityContextHolderAwareRequestFilter 서블릿 API가 SecurityContext 기반으로 동작하도록 HttpServletRequest 정보를 래핑 하는 필터 (다음 필터에게 부가 정보를 제공)
AnonymousAuthenticationFilter 인증이 없는 요청이라면 인가 로직이 동작할 수 있도록 익명 사용자 객체
(AnonymousAuthentication)을 만들어 SecurityContext에 채워 넣는 필터
SessionManagementFilter 인증된 사용자의 세션 정책 및 세션 고정 공격 방어
ExceptionTranslationFilter 인증 필요(401)와 권한 부족(403) 상황을 가로채어 AuthenticationEntryPoint/AccessDeniedHandler로 전달해 일관된 응답을 만드는 필터
FilterSecurityInterceptor 최종적으로 요청 자원에 필요한 권한을 확인하고 AccessDecisionManager로 접근 허용/거부를 결정하는 인가(Authorization) 핵심 필터
💡JWT 기반 인증에서는 UsernamePasswordAuthenticationFilter 대신 커스텀 JWT 인증 필터를 사용한다

인증(Authentication) 처리 흐름 상세

다이어그램의 초록색 영역으로 인증 처리 구조를 나타낸다

컴포넌트 역할
AuthenticationManager 인증 요청을 받아 Provider에 위임
AuthenticationProvider 실제 인증 로직 수행
UserDetailsService 사용자 정보 조회
UserDetail 사용자 정보 객체
GrantedAuthority 사용자 권한 정보
Authentication 인증 결과 객체
AuthenticationSuccessHandler 인증 성공 후 처리
AuthenticationFailureHandler 인증 실패 후 처리
SecurityContextRepository SecurityContext 저장/조회
💡 인증 성공 시 Authentication 객체는 SecurityContext에 저장되고 SecurityContextHolder를
      통해 전역 접근이 가능해진다.

인가(Authorization) 처리 흐름 상세

다이어그램의 주황색 영역으로 인가(권한 검사)를 담당한다

컴포넌트 역할
FilterSecurityInterceptor 인가 처리의 진입점
SecurityMetadataSource 요청에 필요한 권한 정보 제공
AccessDecisionManager 접근 허용 여부 결정
DecisionVoters 권한 투표 수행
AffirmativeBased 하나라도 허용하면 접근 허용
RoleVoter 역할(Role) 기반 권한 판단
AuthenticationEntryPoint 인증되지 않은 접근 처리
AccessDeniedHandler 권한 부족 접근 처리

폼 로그인 인증 처리 순서

 

1. HttpServletRequest에 아이디와 비밀번호가 담겨 서버로 전달 

2. UsernamePasswordAuthenticationFilter가 로그인 요청을 가로챈 뒤 

    UsernamePasswordAuthenticationToken을 만들어 넘겨줌

  • 다음 조건을 만족하는 요청을 처리한다
  • (URL: /login | Method: POST)

3. 전달 받은 UsernamePasswordAuthenticationToken을 AuthenticationManager에게 넘겨 인증 위임 

  • 필터는 “요청에서 자격증명을 꺼내서 인증을 맡기는 역할”이고,
    실제 인증(검증)은 AuthenticationManager/Provider 쪽이 담당한다

4. UsernamePasswordAuthenticationToken을 다시 AuthenticationProvider에게 보냄

5. AuthenticationProvider가 UserDetailsService로 사용자 조회 요청

  • 선택된 AuthenticationProvider는 username을 이용해 사용자 조회를 시도한다
  • UserDetailsService.loadUserByUsername(username)
  • 이 메서드는 “DB에서 사용자 정보를 조회해서 UserDetails로 반환”하는 역할을 한다

6. UserDetailsService가 DB에서 사용자 조회 → UserDetails 생성

  • DB에서 사용자 조회를 성공하면 UserDetails 객체를 생성

7. AuthenticationProvider가 입력 정보와 UserDetails 객체와 비교하여 인증 처리

  • 사용자가 입력한 password DB에서 가져온 password 두 가지 정보를 비교하여 인증
  • 여기서 DB에서 가져온 password는 주로 암호화되어 있어 PasswordEncoder를 이용하여 검증한다
  • passwordEncoder.matches(rawPassword, encodedPassword)
  • (추가로 계정 잠김/만료/비활성 등 상태 검증도 함께 수행될 수 있음)

8. 인증 성공 시 “인증 완료 Authentication” 생성해서 반환

  • 비밀번호 검증까지 완료하면 AuthenticationProvider는 인증이 완료된 Authentication을 생성

9. Authentication이 SecurityContextHolder에 저장됨

  • UsernamePasswordAuthenticationFilter는 인증 성공 결과(Authentication)를 SecurityContextHolder에 저장

10. 성공/실패에 따라 Handler 실행

  • 인증 성공시 AuthenticationSuccessHandler 실행
  • 인증 실패시 AuthenticationFailureHandler 실행

폼 로그인 방식은 Filter가 요청에서 자격증명을 추출하여 인증을 위임하고 Provider가 DB에서 사용자 정보(UserDetails)와 입력 정보를 비교하여 인증을 처리하여 SecurityContxt에 인증 결과를 저장하고 성공/실패 여부에 따라 핸들러 실행하는 순서를 가진다

반응형