0. 들어가며
앞서서 스프링 시큐리티가 무엇인지 또 인증, 인가에 대해서도 정리를 했었고 스프링 시큐리티가 필터 기반으로 동작하는 것도 알아봤다.
오늘은 아이디와 패스워드가 넘어오면 인증 요청을 위임하는, 인증 관리자 역할을 하는 `UsernamePasswordAuthenticationFilter`에 대해서, 가장 많이 사용하는 아이디와 패스워드 기반 폼 로그인을 시도하면 스프링 시큐리티에서는 어떤 절차로 인증 처리를 하는지 공부를 해보려고 한다.
두 가지 다이어그램을 바탕으로 폼 로그인 인증 흐름을 구조 + 실행 흐름으로 정리하고 함께 나오는 용어들도 정리할 것이다.
1. 구조 중심의 흐름
✅ 구조 중심의 흐름도 (Filter → Token → Manager → Provider → UserDetails 등)
1. 클라이언트 로그인 요청
- 사용자가 `/login` 경로로 POST 요청을 보냄
- HTML <form>을 통해 입력한 `username`, `password`가 전송됨
2. `UsernamePasswordAuthenticationFilter`
- 로그인 요청을 감지하고, 전달받은 사용자 정보를 검증함.
- 이후 인증 전용 토큰인 `UsernamePasswordAuthenticationToken`객체 생성
- 이 토큰은 아직 인증되지 않은 상태임
3. 전달받은 인증용 객체(토큰)을 넘겨줌
- 위에서 만든 `UsernamePasswordAuthenticationToken`객체를 `AuthenticationManager` 에게 전달
- 여기서부터는 인증 책임이 `AuthenticationManager`에게 넘어감
4. AuthenticationManager
- 인터페이스. 보통 구현체는 `ProviderManager`
- 전달받은 토큰을 처리할 수 있는 `AuthenticationProvider`에게 위임함
5. 사용자 아이디를 보냄
- `AuthenticationProvider`는 `UserDetailsService`를 호출하여 사용자 정보를 찾음
- username(아이디)을 기반으로 DB 조회됨
6. DB에서 사용자 정보 로딩
- `UserDetailsService`는 DB 등에서 해당 사용자의 정보를 불러옴
- 반환값은 UserDetails 객체로, 사용자 이름, 비밀번호, 권한 등 포함
7. 입력 정보와 `UserDetails` 비교
- `AuthenticationProvider`는 사용자 입력값(특히 비밀번호)을 `UserDetails`에 들어있는 저장된 값과 비교하여 인증 여부를 결정
- 내부적으로는 `PasswordEncoder.matches()` 같은 로직이 실행됨
8. 인증 성공 시 `Authentication ` 반환
- 인증이 성공하면 새로운 Authentication 객체가 생성되어 반환
- 이 객체는 "인증 완료" 상태이며, 사용자의 권한 정보도 포함
9. 인증이 완료되면 `SecurityContextHolder`에 저장
- 이 인증 객체는 `SecurityContext`에 저장되고, SecurityContext는 다시 `SecurityContextHolder`에 보관됨
- 이는 로그인 이후의 요청들에서 사용자 정보를 재사용하기 위함
- 세션 기반 인증 상태 유지가 가능해짐
10. 인증 결과 처리
- 성공하면: AuthenticationSuccessHandler 호출 (기본적으로 메인 페이지로 리다이렉트)
- 실패하면: AuthenticationFailureHandler 호출 (오류 메시지와 함께 로그인 페이지로 이동)
🔒 주요 클래스 정리
구성 요소 | 설명 |
UsernamePasswordAuthenticationToken | 인증 전/후 모두 사용되는 토큰 객체 |
AuthenticationFilter | 필터 체인에서 로그인 요청을 가로채는 필터 |
AuthenticationManager | 인증 처리를 책임지는 매니저 |
ProviderManager | AuthenticationManager의 기본 구현체 |
AuthenticationProvider | 인증 로직을 수행 (비밀번호 비교 등) |
UserDetailsService | 사용자 정보를 불러오는 서비스 |
UserDetails | 사용자 정보가 담긴 객체 |
SecurityContextHolder | 인증 정보 저장소 (ThreadLocal 기반) |
✅ 요약
이 흐름은 Spring Security가 로그인 인증을 어떻게 처리하고 있는지를 정리한 것이다.
커스터마이징을 할 때 `AuthenticationProvider` `UserDetailsService` 그리고 핸들러를 주로 수정한다.
이 인증 흐름은 `formLogin()`을 사용할 경우 기본으로 설정되는 동작이다.