먼저 (1)에서 사용자가 로그인 폼 등을 이용해 Username(로그인 ID)과 Password를 포함한 request를 Spring Security가 적용된 애플리케이션에 전송한다.
사용자의 로그인 요청이 Spring Security의 Filter Chain까지 들어오면 여러 Filter들 중에서 UsernamePasswordAuthenticationFilter
가 해당 요청을 전달 받는다.
사용자의 로그인 요청을 전달 받은 UsernamePasswordAuthenticationFilter
는 Username과 Password를 이용해 (2)와 같이 UsernamePasswordAuthenticationToken
을 생성한다.
UsernamePasswordAuthenticationToken
은 Authentication
인터페이스를 구현한 구현 클래스이며, 여기서의 Authentication
은 아직 인증이 되지 않은 Authentication 이다.
아직 인증되지 않은 Authentication
을 가지고있는 UsernamePasswordAuthenticationFilter
는 (3)과 같이 해당 Authentication
을 AuthenticationManager
에게 전달한다.
AuthenticationManager
는 인증 처리를 총괄하는 매니저 역할을 하는 인터페이스이고, AuthenticationManager
를 구현한 구현 클래스가 바로 ProviderManager
이다.
즉, ProviderManager
가 인증이라는 작업을 총괄하는 실질적인 매니저인 것이다.
현실 세계에서의 매니저처럼 Spring Security의 ProviderManager 역시 직접 인증을 처리하는 것이 아니라 인증을 처리할 누군가를 찾은 뒤, 인증 처리를 대신 맡긴다.
그 누군가가 바로 AuthenticationProvider
이다.
(4)와 같이 ProviderManager
로부터 Authentication을 전달 받은 AuthenticationProvider
는 (5)와 같이 UserDetailsService
를 이용해 UserDetails
를 조회한다.
UserDetails
는 데이터베이스 등의 저장소에 저장된 사용자의 Username과 사용자의 자격을 증명해주는 크리덴셜(Credential)
인 Password, 그리고 사용자의 권한 정보를 포함하고 있는 컴포넌트이다.
그리고 이 UserDetails
를 제공하는 컴포넌트가 바로 UserDetailsService
이다.
UserDetailsService
는 (5)에서 처럼 데이터베이스 등의 저장소에서 사용자의 크리덴셜(Credential)을 포함한 사용자의 정보를 조회합니다.
데이터베이스 등의 저장소에서 조회한 사용자의 크리덴셜(Credential)을 포함한 사용자의 정보를 기반으로 (7)과 같이 UserDetails
를 생성한 후, 생성된 UserDetails
를 다시 AuthenticationProvider
에게 전달한다(8).
UserDetails 를 전달 받은 AuthenticationProvider
는 PasswordEncoder를 이용해 UserDetails
에 포함된 암호화 된 Password와 인증을 위한 Authentication
안에 포함된 Password가 일치하는지 검증한다.
검증에 성공하면 UserDetails를 이용해 인증된 Authentication을 생성한다(9).
만약 검증에 성공하지 못하면 Exception을 발생시키고 인증 처리를 중단한다.
AuthenticationProvider
는 인증된 Authentication을 ProviderManager
에게 전달한다(10).(2)에서의
Authentication
은 인증을 위해 필요한 사용자의 로그인 정보를 가지고 있지만, 이 단계에서ProviderManager
에게 전달한 Authentication은 인증에 성공한 사용자의 정보(Principal, Credential, GrantedAuthorities)를 가지고 있다.
이제 ProviderManager
는 (11)과 같이 인증된 Authentication을 다시 UsernamePasswordAuthenticationFilter에게 전달한다.
인증된 Authentication을 전달 받은 UsernamePasswordAuthenticationFilter는 마지막으로 (12)와 같이 SecurityContextHolder
를 이용해 SecurityContext
에 인증된 Authentication을 저장한다.
SecurityContext는 Spring Security의 세션 정책에 따라서 HttpSession 에 저장되어 사용자의 인증 상태를 유지하기도 하고, HttpSession을 생성하지 않고 무상태를 유지하기도 한다.