
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에 인증 결과를 저장하고 성공/실패 여부에 따라 핸들러 실행하는 순서를 가진다
'Back-end > Spring' 카테고리의 다른 글
| [Spring] Spring Security JWT 로그인 구현 필수 개념 (Session, JWT, Access / Refresh Token) (0) | 2026.01.16 |
|---|---|
| [Spring] Spring Boot + MySQL 연동 & JPA 활용 심화 (2) (0) | 2026.01.03 |
| [Spring] Spring Boot + MySQL 연동 & JPA 활용 심화 (1) (0) | 2025.12.30 |
| [Spring] Spring Data JPA 어노테이션 정리 (초기화 전략,연관관계,Repository) (0) | 2025.11.06 |
| [Spring] Java 제네릭과 람다 개념 정리 및 Service 계층 활용 예제 (0) | 2025.09.23 |