나는 Spring Security동작과정 이해하고 기억하기위해 놀이동산과 티켓, 그리고 검수원으로 생각을 하게되었고 다음과 같이 외웠다.
Spring Security 동작 과정 요약(실생활 예시):
- HTTP 요청 수신 → Spring Security 필터 체인으로 요청 전달.
놀이동산 입장 시도 → 입구에서 고객이 입장할수 있는지 확인해야함(티켓확인) - 필터 체인 처리 → 인증 필터가 요청을 가로채 인증 여부 확인.
입구에서 티켓을 확인하는 과정 → 유요한 티켓을 가지고있는지 확인 - Authentication Manager → 인증 관리자 호출, 사용자 정보 확인.
티켓 검표원 호출 → 검표원이 고객의 티켓이 유효한지 확인(시스템에 기록된것과 일치하는지) - UserDetailsService → 데이터베이스에서 사용자 정보 로드, 비밀번호 검증.
티켓 유형과 고객정보 확인 → 티켓이 일일 회원권(세션기반)인지 연간 회원권(JWT 기반)인지 확인하고 처리 함 - 인증 성공 시 Authentication 생성 → SecurityContext에 인증 정보 저장.
티켓 인증 완료 및 고객 정보 기록 → 유효한 티켓이면, 관리자는 확인표시를 남기고 놀이동산에 입장하게된다
(인증정보는 SecurityContext에 저장) - 인가 확인 → 요청된 리소스에 대한 권한 검사.
놀이기구 이용 가능 여부 확인 → 고객이 놀이기구를 이용시 각각의 놀이기구마다 권한 확인이 필요하다.
(EX 놀이기구 10회권, 해리포터 입장, 자유이용권 등등 의 권한) - 리소스 접근 허용 → 권한이 충분한 경우 요청이 Controller로 전달.
놀이기구 이용 허가 → 고객이 충분한 권한을 가지고있으면 놀이기구를 이용할 수 있게 하고 아니면 거부한다. - 로그아웃 처리 → 인증 정보 제거 및 세션 만료.
놀이동산에서 퇴장 → 고객이 놀이동산을 나갈 때는 티켓인증을 따로 하지 않지만 놀이동산 시스템에서 티켓정보에 퇴장 기록을 하고 이후 더 이상 놀이기구를 이용하지 못하게된다(세션 만료)
이렇게 비유하여 외우게되면 기억에 오래남는거 같다.
아래는 각각의 요청과정을 좀더 자세히 정리하였다.
- HTTP 요청 수신
- 사용자가 브라우저나 클라이언트에서 서버에 HTTP 요청을 보냄
- Spring Security filter chain에서 요청을 우선적으로 처리함, filter chain 은 여러 개의 보안 필터로 구성되어있으며, 각 필터는 요철을 처리하거나 다음 필터로 넘김.
- Spring Security Filter Chain
- 모든 요청은 이 체인을 통과해야한다.
- UsernamePasswordAuthenticationFilter가 가장 중요한 필터인데 이 필터는 로그인 요청인지 확인하고, 로그인 요청이면 인증을 시도한다.
- 필터는 DispatcherServlet 전에 호출되며, 각 필터는 인증, 인가, 세션관리 등을 처리한다.
- Authentication Manager를 통한 인증
- 로그인 요청이 필터에 도달하면, 사용자의 아이디와 비밀번호 같은 인증정보를 받아 AuthenticationManager에 전달한다.
- AuthenticationManager는 요청된 정보를 처리하기위해 AuthenticationProvider를 사용하며 일반적으로는 DaoAuthenticationProvider을 사용하여 데이터베이스에서 유저 정보를 가져와 사용자의 비밀번호를 확인한다.
- UserDetailsService와 비밀번호 검증
- AuthenticationProvider는 UserDetailsService를 호출하여 데이터베이스나 다른 저장소에서 사용자 정보를 가저온다
- 이 과정에서 사용자가 입력한 비밀번호는 PasswordEncoder를 통해 암호화된 상태로 비교되며, 비밀번호가 일치하면 인증에 성공하게된다.
- 인증 토큰 발급
- 인증에 성공하게되면 Authentication 객체가 생성되며, 이를 통해 사용자가 인증되었음을 나타낸다.
- 생성된 Authentication 객체즌 SecurityContextHolder에 저장되며, 이후 요청 대해 인증된 상태로 유지된다.
- 이 과정에서 세션이나 JWT를 사용할 수 있으며, 세션을 사용하면 서버가 상태를 유지하고, JWT를 사용하면 무산태(stateless)방식으로 클라이언트가 토큰을 보유한다.
- 인가(Authorization)
- 인증이 완료되면 인가단계로 넘어가게된다
- Spring Security는 요청한 리소스에 접근할 권한이 있는지 확인한다. 이때 SecurityContext에 저장된 인증 정보를 사용하여 권한을 확인한다.
(이때 권한은 @PreAuthorize, @Secured, 혹은 URL 기반 설정을 통해 이뤄짐) - 권한이 충분하지 않으면, 403 Forbidden 응답이 반환됨
- 리소스 접근 허용
- 사용자가 적절한 권한을 가지고 있다면, 요청은 Controller로 전달되어 해당 리소스에 접근하게 된다
- 이때 필터 체인에 따라 세션 유지 여부, CSRF 보호 여부 등의 추가 보안 검사가 이뤄질 수 있다.
- 로그아웃 처리
- 사용자가 로그아웃을 요청하면, SecurityContext에 저장된 인증 정보를 제거처리한다.
- 로그아웃 처리 후 세션 정보가 삭제되며, JWT를 사용할 경우 서버에서 별도로 처리가 필요하지 않지만, 세션기반 로그아웃이라면 세션이 만료된다.