Spring Security에는 /login과 /logout 요청을 처리하는 메서드(세션저장/세션삭제)가 내부적으로 구현되어 있다. 따라서 개발자는 따로 구현을 하지 않아도 된다. 하지만 어떤식으로 /login POST 요청이 처리되어 세션에 저장되는지 궁금해서 정리해 본다.
<Spring Security 로그인 요청 처리 과정>
① 클라이언트는 아이디와 비밀번호 정보를 담아 서버에게 POST /login 요청
② 스프링시큐리티의 UsernamePasswordAuthenticationFilter 가 중간에서 아이디와 비밀번호를 추출
③ 추출한 아이디와 비밀번호를 AuthenticationManager 에게 주면서 인증 요청
④ AuthenticationManager는 AuthenticationProvider( DaoAuthenticationProvider ) 에게 인증 처리 위임
⑤ DaoAuthenticationProvider는 UserDetailsService를 이용하여 DB를 조회해 UserDetails 객체에 담아 반환
⑥ UserDetails에 저장된 암호화된 비밀번호를 PasswordEncoder를 이용해 실제 입력한 비밀번호와 비교 검증
⑦ 검증이 완료 되면 UserDetails 정보와 추가적인 인증관련 데이터를 Authentication 객체를 생성해서 담는다.
⑧ Authentication 객체를 SecurityContextHolder에 담는다.
⑨ Spritn Security가 세션을 생성해 SecurityContext 정보를 저장
※ 참고 ※
SecurityContextHolder는 SecurityContext 객체를 저장하고 관리한다.
그리고 SecurityContext 객체에는 Authentication 객체가 있다.
왜 8번과 9번이 필요한가?
- 8번: SecurityContextHolder에 Authentication 객체 담기
- SecurityContextHolder에 SecurityContext를 담는 것은 현재 스레드에 대한 인증 정보를 관리하는 방법입니다.
- 여러 스레드에서 동시에 처리되는 요청에 대해 각 스레드가 자신만의 SecurityContext를 가질 수 있도록 해줍니다.
- 즉, 사용자가 로그인하면 Authentication 객체는 SecurityContext에 담기고, 이 SecurityContext가 SecurityContextHolder에 의해 관리됩니다.
- 9번: 세션 생성 및 SecurityContext 저장
- 스프링 시큐리티는 인증 정보를 세션에 저장하여, 사용자가 인증된 상태를 유지하도록 합니다.
- 이 과정에서 SecurityContext를 세션에 저장함으로써, 사용자가 다음 요청을 보낼 때 자동으로 인증 상태를 확인할 수 있습니다.
- 세션이 유지되면 사용자에게 로그인이 필요 없으며, 매 요청마다 인증 정보를 확인하는 비용을 줄일 수 있습니다.
3. 세션과 SecurityContext의 관계
- **SecurityContext**는 인증된 사용자에 대한 정보를 담고 있고, 세션은 이러한 SecurityContext를 저장하여 다음 요청에서 인증 상태를 쉽게 확인할 수 있도록 도와줍니다.
- 따라서 세션에 Authentication 객체를 직접 넣는 대신, SecurityContext를 통해 좀 더 구조적으로 인증 정보를 관리할 수 있습니다.
4. 결론
- 스프링 시큐리티는 SecurityContext를 통해 인증 정보를 관리함으로써, 인증과 세션 관리를 명확하게 분리하고 각 요청에 대해 독립적인 상태를 유지할 수 있습니다.
- 이러한 설계는 스레드 안전성과 유연성을 높이며, 보안성을 향상시킵니다.
따라서, 8번과 9번의 과정은 스프링 시큐리티의 설계 철학과 흐름에 따라 필수적인 단계라 할 수 있습니다.
'springboot' 카테고리의 다른 글
[springboot] @LoginUser 어노테이션 (0) | 2024.10.10 |
---|---|
[springboot] Spring Security 권한 설정 외 @PreAuthorize로 추가 권한 검사 (0) | 2024.10.10 |
[springboot] 스프링부트 2점대에 swagger 3점대 연결 (0) | 2024.04.14 |
[springboot] 유효성 검사 (0) | 2024.04.07 |
[springboot] 엔티티 int VS Integer 타입 차이 (0) | 2024.04.06 |