Spring 7기 프로젝트/뉴스피드 팀 프로젝트
Spring Security 작동 순서 정리
JuNo_12
2025. 5. 26. 17:49
나의 코드에서 작동하는 방식
요청 → 인증 → 인가 → 컨트롤러 → 서비스 → DB
1. 클라이언트가 API 요청
예: POST /api/schedules (일정 등록 요청)
2. Spring Security Filter Chain 작동
- Spring Security가 HTTP 요청을 가로채서 인증 및 권한 확인
- SecurityFilterChain에 정의된 필터들 실행
- 예를 들어, 세션에서 인증 정보 읽어 SecurityContextHolder에 세팅
- 현재 요청에 대해 인증이 없으면 401 Unauthorized 처리 (CustomAuthenticationEntryPoint 실행)
- 요청이 /api/users/signup이나 /api/auth/login이 아니면 인증이 있어야 통과
클라이언트 로그인 요청
↓
AuthService.login()
↓
authenticationManager.authenticate(...)
↓
CustomUserDetailsService.loadUserByUsername(email)
↓
사용자 DB 조회 (User 엔티티 반환)
↓
CustomUserDetails(user) 생성
↓
UsernamePasswordAuthenticationToken(authentication 객체) 생성
(principal = CustomUserDetails)
↓
SecurityContext context = SecurityContextHolder.getContext()
context.setAuthentication(authentication)
↓
SecurityContextHolder 내에 Authentication 객체 저장됨
(Authentication -> CustomUserDetails 포함)
이후 요청 시
요청 처리 시
↓
SecurityContextHolder.getContext().getAuthentication()
↓
Authentication 객체 획득
↓
authentication.getPrincipal() → CustomUserDetails 반환
↓
User 정보 활용 가능
3. 인증된 사용자 정보 확인
- 인증 성공한 경우, SecurityContextHolder.getContext().getAuthentication() 내부에 CustomUserDetails가 담겨 있음
- 이때 @AuthenticationPrincipal UserDetails userDetails가 컨트롤러 메서드 인자에 주입됨
- userDetails.getUsername()은 이메일 주소를 반환 (즉, CustomUserDetails.getUsername())
4. 컨트롤러 (ScheduleController) 호출
- 스프링 MVC가 요청 URL과 HTTP 메서드를 기반으로 ScheduleController의 해당 핸들러 메서드 실행
- 예: createSchedule() 메서드가 호출됨
더보기
1. 인증 시점 (AuthService.login())
- 사용자가 로그인 시도 → AuthenticationManager가 인증 처리 → 인증 성공 시 Authentication 객체가 만들어짐 (여기엔 CustomUserDetails 포함).
- 이 Authentication 객체를 SecurityContextHolder.getContext().setAuthentication(authentication) 으로 저장.
2. 인증 정보 저장 위치
- SecurityContextHolder는 스레드 로컬(ThreadLocal)에 SecurityContext를 저장해서 현재 쓰레드에서만 접근 가능하게 함.
- 그러나 HTTP 요청이 여러 번 오고 나갈 때마다 쓰레드가 바뀌기 때문에,
- Spring Security는 이 SecurityContext를 세션(HttpSession)에 저장함 (HttpSessionSecurityContextRepository가 담당).
- 이렇게 하면 클라이언트가 보내는 세션 ID 쿠키를 통해, 다음 요청 때도 인증 정보를 찾을 수 있음.
3. 이후 요청에서 인증 정보 접근
- 클라이언트가 서버에 요청을 보낼 때마다,
- Spring Security 필터가 세션에서 SecurityContext를 읽어 SecurityContextHolder에 세팅.
- 그래서 컨트롤러, 서비스 어디서든 SecurityContextHolder.getContext().getAuthentication() 으로 인증 정보에 접근 가능.
- 이 Authentication 안에 CustomUserDetails가 있고, 그걸 통해 현재 로그인된 유저 정보 조회 가능.
내부 호출 흐름 요약 (예: 일정 등록)
HTTP Request (POST /api/schedules)
↓
Spring Security FilterChain
↓
인증 성공 → SecurityContextHolder에 인증정보 저장
↓
ScheduleController.createSchedule()
↓
userService.findByEmailAddressOrThrow(userDetails.getUsername())
↓
ScheduleService.createSchedule()
↓
findUserById(userId)
↓
scheduleRepository.save(new Schedule(...))
↓
ScheduleCreationResponseDto 반환
↓
ScheduleController → ResponseEntity 반환
↓
HTTP Response